async/await 语法

  • 异步回调容易产生 callback hell(回调地狱)
  • Promise then catch 链式调用,但也是基于回调函数
  • async/await 是同步语法,彻底消灭回调函数,代码演示:
//加载图片  
function loadImg(src) {  
    const p = new Promise((resolve, reject) => {  
        const img = document.createElement('img')  
        img.onload = () => {  
            resolve(img)  
        }  
        img.onerror = () => {  
            const err = new Error(`图片加载失败 ${src}`)  
            reject()  
        }  
  
        img.src = src  
    })  
  
    return p  
}  
  
const src1 = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'  
const src2 = 'https://box.bdimg.com/static/fisp_static/common/img/searchbox/logo_news_276_88_1f9876a.png'  
  
// !用于解决报错 Uncaught TypeError: "https..." is not a function is not a function  
!(async function(){  
    // 同步的写法  
    const img1 = await loadImg1()//也可以直接用 loadImg(src1)  
    console.log(img1.width,img1.height)  
  
    const img2 = await loadImg2() //也可以直接用 loadImg(src2)  
    console.log(img2.width,img2.height)  
})()  
  
async function loadImg1(){  
    const img1 = await loadImg(src1)  
    return img1  
}  
  
async function loadImg2(){  
    const img2 = await loadImg(src2)  
    return img2  
}

async/await 和 Promise 的关系

  • async/await 是消灭异步回调的终极武器
  • 但和 Promise 并不互斥,反而两者相辅相成
  • 执行 async 函数,返回的是 Promise 对象
async function fn1(){
    return 100
    // return Promise.resolve(200)
}
const res1 = fn1() // 执行 async 函数,返回 Promise 对象
console.log('res1',res1) // res1 Promise
res1.then(data=>{
    console.log('data1',data) // data1 100
})
  • await 相当于 Promise 的 then
async function fn1(){
    return 100
    // return Promise.resolve(200)
}
!(async function(){
    const p1 = Promise.resolve(300)
    const data = await p1 // await 相当于 Promise then
    console.log('data',data) // data 300
})()
!(async function(){
    const data1 = await 400 // 直接返回 400
    console.log('data',data1) // data 400
})()
!(async function(){
    const data2 = await fn1() // await 相当于 Promise.resolve(100)
    console.log('data',data2) // data 100
})()
  • try...catch 可捕获异常,代替了 Promise 的 catch
!(async function () {
    const p4 = Promise.reject('err') // rejected状态
    try {
        const res4 = await p4
        console.log('res4', res4) // 不执行
    } catch (e) {
        console.error('err4',e) //err4 err try…catch 相当于 Promise catch
    }
})()
// 没有 try…catch 无法捕获错误
!(async function(){
    const p5 = Promise.reject('err1') // rejected状态
    const res5 = await p5 // await -> then,下面不会执行
    console.log('res5',res5) // 不执行
})()

异步的本质

  • async/await 是消灭异步回调的终极武器
  • JS 还是单线程,还得是有异步,还得是基于 event loop
  • async/await 只是一个语法糖,代码演示:
async function async1() {  
    console.log('async1 start') // step 2  
    await async2() //undefined  
    // await 的后面,都可以看做是 callback 里的内容,即异步  
    // 类似 event loop,setTimeout(function(){ console.log('async1 end')})  
    // 或 Promise.resolve().then(()=>{console.log('async1 end')})  
    console.log('async1 end') // step 5  
}  
  
async function async2() {  
    console.log('async2') // step 3  
}  
  
console.log('script start') // step 1  
async1()  
console.log('script end') // step 4  
// 同步代码已经执行完(event loop)  
  
// script start  
// async1 start  
// async2  
// script end  
// async1 end

再看一个例子:

async function async1() {  
    console.log('async1 start') // step 2  
    await async2()  
  
    // 下面都是异步回调 callback 的内容  
    console.log('async1 end') // step 5  
    await async3()  
  
        // 下面都是异步回调 callback 的内容  
        console.log('async1 end 2') // step 7  
}  
  
async function async2() {  
    console.log('async2') // step 3  
}  
  
async function async3(){  
    console.log('async3') // step 6  
}  
  
console.log('script start') // step 1  
async1()  
console.log('script end') // step 4  
// 同步代码已经执行完(event loop)  
  
// script start  
// async1 start  
// async2  
// script end  
// async1 end  
// async3  
// async1 end 2

补充 for ... of 异步的使用

  • for ... in (以及 forEach for )是常规的同步遍历
  • for ... of 常用于异步的遍历
function muti(num) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(num * num)
        }, 1000)
    })
}
const nums = [1, 2, 3]
nums.forEach(async (i) => { // 1秒后同步执行
    const res = await muti(i) // 相当于 Promise 的 then
    console.log(res) // 1 4 9
})
!(async function () {
    for (let i of nums) { // 1秒执行一个
        const res = await muti(i) // 相当于 Promise 的 then
        console.log(res) // 1 4 9
    }
})()

标签: none

添加新评论