欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > async/await 原理

async/await 原理

2025/5/9 13:18:49 来源:https://blog.csdn.net/qq_42825643/article/details/147796789  浏览:    关键词:async/await 原理

大家都知道async和await是语法糖,那么我们今天就来剖析一下不使用语法糖要怎么实现同样的功能

文章目录

  • 一、生成器
  • 二、实现async/await

一、生成器

async/await 的行为类似于 可暂停和恢复的函数,这正是生成器的特性,让我们首先来补一下生成器的知识:

通过function* 声明一个生成器函数。生成器函数可以退出,并在稍后重新进入,其上下文会在重新进入时保存。箭头函数不能定义生成器函数

通过yield 关键字用于暂停和恢复生成器函数

调用生成器函数会返回迭代器对象Generator

迭代器对象的 next() 方法被调用时,生成器函数的主体会被执行,直到遇到下一个yield

next()方法返回一个对象,其 value 属性包含了 yield 表达式的值,done 属性是布尔类型,表示生成器是否已经返回了最后一个值

在生成器中执行 return 语句会使生成器结束

function* a() {yield 1;yield 2;return 3
}
b = a()  // Generator对象
b.next() // {value: 1, done: false}
b.next() // {value: 2, done: false}
b.next() // {value: 3, done: true}

二、实现async/await

1.环境准备;准备一个异步函数和一个生成器函数,

function fn(nums) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(nums * 2);}, 1000);});
}function* gen() {const num1 = yield fn(1);const num2 = yield fn(num1);const num3 = yield fn(num2);return num3;
}

准备一个async函数作为对照

async function asyncFn() {const num1 = await fn(1)const num2 = await fn(num1)const num3 = await fn(num2)return num3
}
asyncFn().then(res => console.log(res)) // 3秒后输出 8

2.编写一个函数,接收gen函数,返回具有async函数功能的函数

// 1.async函数始终返回Promise
function myAsync(gen){return ()=>{return new Promise((resolve,reject)=>{})}
}

3.实现具体细节

function myAsync(gen) {return () => {return new Promise((resolve, reject) => {const g = gen();const next1 = g.next();next1.value.then((res) => {const next2 = g.next(res);next2.value.then((res2) => {const next3 = g.next(res2);next3.value.then((res3) => {const next4 = g.next(res3);resolve(next4.value);});});});});};
}
const asyncGen = myAsync(gen);asyncGen().then((res) => console.log(res));   // 3秒后输出 8

到这里已经实现了基本功能,输出与asyncFn函数的输出一致,下一步我们改写函数,将固定的yield改为动态

4.修改代码

function myAsync(gen) {return () => {const g = gen(arguments);return new Promise((resolve, reject) => {// 递归执行function next(key, args) {// 异常处理let res;try {res = g[key](args);} catch (err) {return reject(err);}const { value, done } = res;if (done) {return resolve(value); // 递归退出条件} else {return Promise.resolve(value).then((res) => next("next", res),(err) => next("throw", err));}}next("next");});};
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词