JS Asynchronous Advancement 3: async, await

async/await

  • Grammar introduction
  • Relationship with Promises
  • asynchronous nature
  • for...of

There are a lot of async interview questions like

  • async returns directly, what is it?
  • async returns promise directly
  • No promise is added after await
  • Wait, we need to find a rule

Grammar introduction

Write asynchronously in a synchronous way.

function loadImg(src) {
    const promise = new Promise((resolve, reject) => {
        const img = document.createElement('img')
        img.onload = () => {
            resolve(img)
        }
        img.onerror = () => {
            reject(new Error(`图片加载失败 ${src}`))
        }
        img.src = src
    })
    return promise
}

async function loadImg1() {
    const src1 = 'http://www.imooc.com/static/img/index/logo_new.png'
    const img1 = await loadImg(src1)
    return img1
}

async function loadImg2() {
    const src2 = 'https://avatars3.githubusercontent.com/u/9583120'
    const img2 = await loadImg(src2)
    return img2
}

(async function () {
    // 注意:await 必须放在 async 函数中,否则会报错
    try {
        // 加载第一张图片
        const img1 = await loadImg1()
        console.log(img1)
        // 加载第二张图片
        const img2 = await loadImg2()
        console.log(img2)
    } catch (ex) {
        console.error(ex)
    }
})()
复制代码

Relationship with Promises

  • The results returned by the async function are all Promise objects (if the function does not return a Promise, it will be automatically encapsulated)
async function fn2() {
    return new Promise(() => {})
}
console.log( fn2() )

async function fn1() {
    return 100
}
console.log( fn1() ) // 相当于 Promise.resolve(100)
复制代码
  • await followed by a Promise object: it will block subsequent code, wait for the state to become resolved, then get the result and continue execution
  • await followed by non-Promise objects: will return directly
(async function () {
    const p1 = new Promise(() => {})
    await p1
    console.log('p1') // 不会执行
})()

(async function () {
    const p2 = Promise.resolve(100)
    const res = await p2
    console.log(res) // 100
})()

(async function () {
    const res = await 100
    console.log(res) // 100
})()

(async function () {
    const p3 = Promise.reject('some err')
    const res = await p3
    console.log(res) // 不会执行
})()
复制代码
  • try...catch catch rejected status
(async function () {
    const p4 = Promise.reject('some err')
    try {
        const res = await p4
        console.log(res)
    } catch (ex) {
        console.error(ex)
    }
})()
复制代码

In summary:

  • async wrapping Promise
  • await handles Promise success
  • try...catch handles Promise failures

asynchronous nature

await is a synchronous way of writing, but the essence is still an asynchronous call.

async function async1 () {
  console.log('async1 start')
  await async2()
  console.log('async1 end') // 关键在这一步,它相当于放在 callback 中,最后执行
}

async function async2 () {
  console.log('async2')
}

console.log('script start')
async1()
console.log('script end')
复制代码

That is, as long as it is encountered await, the following code is equivalent to being placed in the callback.

for...of

// 定时算乘法
function multi(num) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(num * num)
        }, 1000)
    })
}

// // 使用 forEach ,是 1s 之后打印出所有结果,即 3 个值是一起被计算出来的
// function test1 () {
//     const nums = [1, 2, 3];
//     nums.forEach(async x => {
//         const res = await multi(x);
//         console.log(res);
//     })
// }
// test1();

// 使用 for...of ,可以让计算挨个串行执行
async function test2 () {
    const nums = [1, 2, 3];
    for (let x of nums) {
        // 在 for...of 循环体的内部,遇到 await 会挨个串行计算
        const res = await multi(x)
        console.log(res)
    }
}
test2()
复制代码

Executing an async function returns a Promise object 

await is equivalent to then of Promise

try...catch catches exceptions instead of Promise's catch

image.pngInterpretation of the upper right picture: async returns Promise, await returns then, and an error after await will terminate the execution, which can be captured with try...catch

Guess you like

Origin juejin.im/post/7078327167393906724