3分钟带你解决async和await疑难杂症

前言

为什么要学习async/await

出现async/await是因为在使用Promise时,需要频繁地使用.then() 方法来处理异步操作的结果,这样会导致代码可读性较差,而且错误处理也比较麻烦。

使用 async/await 可以让异步代码的写法更加简洁和直观,使代码更易读、易懂和易维护。

最重要的一点是有些面试会考

async和await语法和用法

async和await的基本用法

  1. async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
function timeout(ms) {
  return new Promise((res) => {
    setTimeout(res, ms);
  });
}
async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value);
}
asyncPrint('hello world', 1000);
//在1s后输出hello world
  1. async函数有多种使用形式
// 函数声明
async function foo() {}
// 函数表达式
const foo = async function () {};
// 对象的方法
let obj = {async foo(){}};
obj.foo().then()
// 箭头函数
const foo = async () => {};
// Class 的方法
class Test{async getRequest(){}}
const test = new Test()
test.getRequest().then()

async和await语法

1.async函数返回一个 Promise 对象,async函数内部return语句返回的值,会成为then方法回调函数的参数。

2. 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

3.await 后面跟的是一个 Promise 对象,如果不是,则会包裹一层 Promise.resolve()

async函数实现原理

async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里,简而言之,就是 Generator 函数的语法糖。

Generator函数?

function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态

Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。


// generator函数基本用法
function* generator() {
  yield 1;
  yield 2;
  yield 3;
  return 4;
}
const self = generator();
console.log(self.next()); //{ value: 1, done: false }
console.log(self.next()); //{ value: 2, done: false }
console.log(self.next()); //{ value: 3, done: false }
console.log(self.next()); //{ value: 4, done: true  }
//如果不写return 则调用第四次self.next()为{ value: undefined, done: true}
//generator+promise使用
function* generator() {
  yield Promise.resolve("1");
  yield Promise.resolve("2");
  yield Promise.resolve("3");
  return Promise.resolve("4");
}
const self = generator();
const next1 = self.next();
next1.value.then((res1) => {
  console.log(res1);
  const next2 = self.next();
  next2.value.then((res2) => {
    console.log(res2);
    //...往下推
  });
});
//1,2

接下来是原理实现 spawn函数就是自动执行器

async function fn(args) {
  // ...
}
// 等同于下面代码
function fn(args) {
  return spawn(function* () {
  });
}
function spawn(genFn){
   return new Promise((resolve, reject) => {
  const gen = genFn();
  function step(nextF) {
    let next;
    try {
      next = nextFn();
    } catch (e) {
      return reject(e);
    }
    if (next.done) {
      return resolve(next.value);
    }
    Promise.resolve(next.value).then(
      function (v) {
        step(function () {
          return gen.next(v);
        });
      },
      function (e) {
        step(function () {
          return gen.throw(e);
        });
      }
    );
  }
  step(function () {
    return gen.next(undefined);
  });
});

}

到这里就结束了,更多作为自我学习,希望对你有所帮助

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值