風雲論壇脚本中心 → 浏览:帖子主题
* 帖子主题:使用生成器函数模拟实现 async/await 效果
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 1 楼 ] 回复
async/await 是现今比较流行的一种开发模式,传闻它只是基于生成器函数的一个语法糖,我们来尝试一下使用失传已久的生成器函数来复现 async/await 模式。

第一种方式:

[您可以先修改代码再运行]

由于生成器内部无法直接访问 gen 对象,需要先通过 yield 将 gen 传进去,所以这种写法感觉有些怪怪的。
2023/8/5 16:48:48 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 2 楼 ] 回复
第二种方式:

[您可以先修改代码再运行]

这里我们为了让生成器可以直接访问 gen 对象,增加了一个内部函数,写代码时会多一层缩进。
2023/8/5 16:50:13 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 3 楼 ] 回复
第三种方式:

[您可以先修改代码再运行]

封装了一个runGen 的方法来运行生成器函数,生成器内部可以使用 this.gen 来调用 next 方法。
2023/8/5 16:51:54 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 4 楼 ] 回复
再来一个 async/await 方式的对比:

[您可以先修改代码再运行]

看起来好像只是将 function* 改成了 async function,yield 改成了 await。那么,那种方式更优雅呢?😊
2023/8/5 16:58:14 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 5 楼 ] 回复
需要注意的是,yield func() 内部不能同步调用 gen.next(),yield gen.next() 会报错的,必须等 yield 语句完成后才能 gen.next(),例如可以使用:
// var num = yield gen.next(123); // 错误
var num = yield setTimeout(() => gen.next(123), 0);
而 async/await 默认做了 Promise 异步处理,例如,使用 await console.log(123); 相当于 await Promise.resolve(console.log(123)); 因此并不会出现运行时错误。
2023/8/5 18:06:37 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 6 楼 ] 回复
再来一个 yield* 的使用(可以使用 return 返回结果,更像 async/await 写法):

[您可以先修改代码再运行]

2023/8/5 23:06:50 IP:已设置保密
pojin (ID: 2)
等级:风云使者
积分:251
发帖:1
来自:保密
注册:2022/3/30 11:42:27
造访:2024/5/1 8:09:33
[ 第 7 楼 ] 回复
赞~~
2023/8/5 23:52:25 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 8 楼 ] 回复
搭配 yield new Promise 或者 yield function,加上迭代器原理,无需传入 gen 对象。

[您可以先修改代码再运行]

2023/8/6 21:41:59 IP:已设置保密
admin11 (ID: 46)
等级:新手上路
积分:7
发帖:1
来自:保密
注册:2023/11/24 17:42:27
造访:2023/11/24 17:42:27
[ 第 9 楼 ] 回复
好。不过还是感觉 async/await 好用。
2023/11/24 17:43:21 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 10 楼 ] 回复
更简洁的写法,支持执行完毕回调:

[您可以先修改代码再运行]

2024/4/19 21:24:50 IP:已设置保密
分页: 1, 共 1 页
快速回复主题
账号/密码
用户: 没有注册? 密码:
评论内容