🔥🔥🔥async/await基本用法与原理实现

前言

为什么要学习async/await

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

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

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

async和await语法和用法

async和await的基本用法

  1. async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
js 复制代码
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函数有多种使用形式
js 复制代码
// 函数声明
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方法回调函数的参数。

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

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

async函数实现原理

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

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

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

js 复制代码
// 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函数就是自动执行器

js 复制代码
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);
  });
});

}

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

相关推荐
10mAh1 分钟前
【Linux】error while loading shared libraries 怎么解决?——ldd、RPATH 与动态链接排错
java·linux·前端
深念Y6 分钟前
stable-diffusion.cpp 的 FLUX.2 Klein 9B 分步
java·前端·数据库
小帅不太帅10 分钟前
1.5M 参数的 OCR 模型,我把它跑进了浏览器
前端·javascript·ai编程
风骏时光牛马19 分钟前
AI编程场景下故障根因分析与复盘总结
前端
Sterting38 分钟前
Element-Plus 入门与整体布局
前端·vue.js·elementui
程序员黑豆8 小时前
Java 注释详解:单行、多行与文档注释的完整指南
java·前端·ai编程
剪刀石头布啊8 小时前
antd中可编辑表格中巧用useWatch实现联动高性能效果,以及定制延伸学习
前端
油丶酸萝卜别吃9 小时前
前端转全栈学习路线
前端·学习
浮生望9 小时前
前端路由进阶:History API原理与手写HistoryRouter
前端
陆枫Larry9 小时前
JavaScript 中的竞态是什么,为啥会有竟态?
前端