🔥🔥🔥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);
  });
});

}

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

相关推荐
哈__12 分钟前
ReactNative项目OpenHarmony三方库集成实战:lottie-react-native
javascript·react native·react.js
哈罗哈皮14 分钟前
trea也很强,我撸一个给你看(附教程)
前端·人工智能·微信小程序
就是个名称24 分钟前
echart绘制天顶图
linux·前端·javascript
im_AMBER26 分钟前
Leetcode 147 零钱兑换 | 单词拆分
javascript·学习·算法·leetcode·动态规划
arvin_xiaoting1 小时前
OpenClaw学习总结_II_频道系统_5:Signal集成详解
java·前端·学习·signal·ai agent·openclaw·signal-cli
哆啦A梦15881 小时前
统一返回包装类 Result和异常处理
java·前端·后端·springboot
saadiya~1 小时前
从插件冗余到极致流畅:我的 Vue 3 开发环境“瘦身”实录
前端·javascript·vue.js
Timer@2 小时前
LangChain 教程 03|快速开始:10 分钟创建第一个 Agent
前端·javascript·langchain
亿元程序员2 小时前
十年游戏程序员开箱实测:这台显示器,彻底改写了我的游戏开发日常
前端
凉城a2 小时前
前端性能优化解决方案
前端·性能优化