ES6 - Generator函数和async/await方法

本文探讨了处理异步操作的几种方法,包括回调函数、Promise、generator函数和async/await。通过示例展示了如何用这些方法实现任务顺序执行,特别强调了async/await在处理依赖前一个任务结果的异步操作时的便利性。最后,通过一个计算序列求和的示例,展示了async/await如何简化代码并提高可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们来详细了解一下另外两种的处理异步同步化的方法。
先来看一个实例。

// 使得下面代码按照p2, p1的顺序打印
let p1 = function () {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('p1');
                resolve('p1');
            }, 1000)
        })
    }

    let p2 = function () {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('p2');
                resolve('p2');
            }, 2000)
        })
    }

回调函数

p2();
setTimeout(() => [
    p1()
])

Promise

p2().then(() => {
  p1();
})

generator函数

function* gen() {
    yield p2();
    yield p1();
}
let g = gen();
g.next();
g.next();
// 但是无法完成上述的任务

async/await

async function asy1() {
  let p1 = await p2();
  console.log(p2); // p2
  let p2 = await p1();
  console.log(p1); // p1
}
generator 函数

接下来举个例子来详细说明一下generator函数的用法:

 function* gen1() {
     // 1. yield 需要 next() 执行
    // 2. 阻止下面的代码执行
    // 3. 后面的内容为返回值,通过value获取
    yield 1;
    console.log('gen1');
    yield 2;
    console.log('gen2');
    return 123;
    yield 3; // return 下的所有 yield 不能执行了
}

let g1 = gen1();
console.log(g1);
console.log(g1.next().value);  // 获取第一个yield 的返回值
console.log(g1.next().value);  // 获取第二个yield 的返回
console.log(g1.next().value);  // 获取第三个yield 的返回
console.log(g1.next().value);  // 获取第四个yield 的返回
async/await
  • 在普通函数前面加上关键字async 就是async函数
  • await 只能在async中使用
  • await 后面必须赋值promise 实例(可以是new,.then, return, all, async)
  • await 的返回值 相当于 then 的回参赋值(关键看await 后promise 是如何产生的)
  • resolve
  • then 中 return
  • 返回 return await 的返回结果。需要用await接受

如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。

如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

//它就是 Generator 函数的语法糖。
 function delay(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data);
        },1000)
    })
}

async function a() {
    try{
      const p1 = await delay('1')
      console.log(p1);
      const p2 = await delay('2')
      console.log(p2);
      const p3 = await delay('3')
      console.log(p3);
    }catch(err){
      console.log('这里可以捕获到try 中执行的错误', err);
    }
}
// a();

为啥说async/await的是非常有用的,在处理事件的时候需要用到上一个的数据的时候它的作用就有体现了。

// 实例
function takeLongTime(arr) {
    return arr.reduce((pre, sum) => {
       return pre + sum
    },0);
}
function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime([n]);
}
function step2(m, n) {
    console.log(`step2 with ${m} and ${n}`);
    return takeLongTime([m,n]);
}
function step3(k, m, n) {
    console.log(`step3 with ${k}, ${m} and ${n}`);
    return takeLongTime([k,m,n]);
}

async function doIt() {
    console.time('doIt');
    const time = 300; 
    const time1 = await step1(time);
    const time2 = await step2(time, time1);
    const result = await step3(time, time1 ,time2);
    console.log(`result is ${result}`);
    console.timeEnd('doIt');
}
doIt();
// 运行结果
step1 with 300
25.async&await.html:69 step2 with 300 and 300
25.async&await.html:73 step3 with 300, 300 and 600
25.async&await.html:83 result is 1200
25.async&await.html:84 doIt: 0.868896484375 ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值