async/await使用

es2017中十分好用async/await语法糖,
相较于promise进行了更一步的封装.

编写第一个 async/await 函数

promise版本

const fentch = require('node-fetch')

function getZhihuColumn(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    fentch(url)
        .then(rawData => rawData.json())
        .then(jsonData => console.log(jsonData.id))
}

getZhihuColumn("feweekly")
➜  src node async.js
feweekly

async版本

async function getZhihuColumnAsync(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const rawData = await fentch(url)
    const jsonData = await rawData.json()
    console.log(jsonData.id)
}

getZhihuColumnAsync("feweekly")
➜  src node async.js
feweekly

将 async 函数用在 promise chain 中

async function getZhihuColumnAsync1(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const response = await fentch(url)
    const column = await response.json()
    console.log(`INTRO:${column.intro}`)
    return column//async会将返回结果封装成promise对象,这里与return await response.json()等效
}

getZhihuColumnAsync1("feweekly")
    .then(data => console.log(data.id))
➜  src node async.js
INTRO:在前端领域跟上时代的脚步,广度和深度不断精进
feweekly

把任意类型的函数转成 async 风格

getZhihuColumnAsync = async (id) => {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const response = await fentch(url)
    return await response.json()
}

//getZhihuColumnAsync("feweekly")
//    .then(data => console.log(data.id))

(async () => {
    const json = await getZhihuColumnAsync("feweekly")
    console.log(json.id)
})()
class APIClient {
    async getZhihuColumnAsync(id) {
        const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
        const response = await fentch(url)
        return await response.json()
    }
}

(async () => {
    var client = new APIClient()
    const json = await client.getZhihuColumnAsync("feweekly")
    console.log(json.id)
})()

处理 async 函数中的错误

async function getZhihuColumnAsync4(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const response = await fentch(url)
    if (response.status !== 200) {
        throw new Error(response.statusText)
    }
    return await response.json()
}

var showJson = async (id) => {
    try {
        var json = await getZhihuColumnAsync4(id)
        console.log(json)
    } catch (err) {
        console.error(err)
    }
}

showJson("feweekly")

处理多个 await 操作的并行串行

async串行执行多个异步任务

function sleep(delay = 2000) {
    return new Promise(resolve => {
        setTimeout(resolve, delay)
    })
}
async function getZhihuColumnAsync(id) {
    await sleep(2000)
    const response = await fentch(`https://zhuanlan.zhihu.com/api/columns/${id}`)
    return await response.json()
}

async function showInfo() {
    console.time("showInfo")
    const feweekly = await getZhihuColumnAsync("feweekly")
    const toolingtips = await getZhihuColumnAsync("toolingtips")
    console.log(feweekly.id)
    console.log(toolingtips.id)
    console.timeEnd("showInfo")
}

showInfo() //feweekly toolingtips showInfo: 4321.562ms

async并行执行多个异步任务

async function getZhihuColumnAsync(id) {
    await sleep(2000)
    const response = await fentch(`https://zhuanlan.zhihu.com/api/columns/${id}`)
    return await response.json()
}

async function showInfo() {
    console.time("showInfo")
    const feweeklyPromise = getZhihuColumnAsync("feweekly")
    const toolingtipsPromise = getZhihuColumnAsync("toolingtips")
    const feweekly = await feweeklyPromise
    const toolingtips = await toolingtipsPromise
    console.log(feweekly.id)
    console.log(toolingtips.id)
    console.timeEnd("showInfo")
}

showInfo() //feweekly toolingtips showInfo: 2365.843ms

使用 Promise.all() 并行

async function showInfo() {
    console.time("showInfo")
    const [feweekly, toolingtips] = await Promise.all([
        getZhihuColumnAsync6("feweekly"),
        getZhihuColumnAsync6("toolingtips")
    ])
    console.log(feweekly.id)
    console.log(toolingtips.id)
    console.timeEnd("showInfo")
}

//showInfo() //feweekly toolingtips showInfo: 2365.843ms

结合 await 和任意兼容 .then() 的代码

const bluebird = require('bluebird')

async function foo() {
    console.time("showInfo")
    await bluebird.delay(2000)
    console.timeEnd("showInfo")
}
foo()

在 for 循环中正确的使用 await

循环串行异步任务

const bluebird = require('bluebird')
async function getZhihuColumnAsync(id) {
    await bluebird.delay(2000)
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const response = await fentch(url)
    return await response.json()
}

async function showInfo() {
    console.time("showInfo")
    const names = ["feweekly", "toolingtips"]
    for (const name of names) {
        const response = await getZhihuColumnAsync(name)
        console.log(response.id)
    }
    console.timeEnd("showInfo")
}

showInfo() //feweekly toolingtips showInfo: 4355.618ms

循环并行异步任务

const bluebird = require('bluebird')
async function getZhihuColumnAsync(id) {
    await bluebird.delay(2000)
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
    const response = await fentch(url)
    return await response.json()
}

async function showInfo() {
    console.time("showInfo")
    const promises = ["feweekly", "toolingtips"].map(item => getZhihuColumnAsync(item))
    for (const promise of promises) {
        const response = await promise
        console.log(response.id)
    }
    console.timeEnd("showInfo")
}

showInfo() //feweekly toolingtips showInfo: 2196.069ms

async_await详解(彻底摆脱回调地狱)

你可能感兴趣的:(javascript)