关键在于若何等待前面的 setTimeout 触发还调后再履行下一轮轮回。如不雅应用 Generator,我们可以推敲在 setTimeout 后 yield 出去(控制流返还给浏览器),然后在 setTimeout 触发的回调函数中 next,将控制流交还回给代码,履行下一段轮回。
- let iter;
- function* run() {
- for (let i = 1; i < 10; ++i) {
- setTimeout(() => iter.next(), 1000);
- yield; // 等待膳绫擎 setTimeout 履行完毕
- console.log(i);
- }
- }
- iter = run();
- iter.next();
代码的履行次序是如许:
- 请求 run,获得一个迭代器 iter。留意此时并未真正履行 run 的函数体。
- 调用 iter.next(),履行 run 的函数体。
- 轮回开端,i 初始化为 1。
- 履行 setTimeout,启动一个准时器,回调函数延后 1 秒履行。
- 碰到 yield(即 yield undefined),控制流返回到最后的 iter.next() 之后。因为后面没有其他代码了,浏览器获得控制权,响应用户事宜,履行其他异步代码等。
- 1 秒后,setTimeout 超时,履行回调函数 () => iter.next()。
- 调用 iter.next()。大年夜前次 yield 出去的处所持续往下履行,即 console.log(i),输出 i 的值。
- 一次轮回停止,i 自增为 2,回到第 4 步持续履行
- ……
如许即实现了相伴随步 sleep 的请求。
async、await——用同步语法写异步代码
膳绫擎的代码毕竟须要手工定义迭代器变量,还要手工 next;更重要的是与 setTimeout 紧耦合,无法通用。
我们知道 Promise 是异步编程的将来。能不克不及把 Promise 和 Generator 结合应用呢?如许推敲的结不雅就是 async 函数。
用 async 获得代码如下
- setTimeout(() => {
- console.log(1);
- }, 1000);
- function timeout(delay) {
- return new Promise(resolve => {
- setTimeout(resolve, delay);
- });
- }
- async function run() {
- for (let i = 1; i < 10; ++i) {
- await timeout(1000);
- console.log(i);
- }
- }
- run();
按照 Chrome 的设计文档,async 函数内部就是被编译为 Generator 履行的。run 函数本身会返回一个 Promise,用于使主调函数得知 run 函数什么时刻履行完毕。所以 run() 后面也可以 .then(xxx),甚至直接 await run()。
留意有时刻我们切实其实须要几个异尘事宜并行履行(比如调用两个接口,等两个接口都返回后履行后续代码),这时就不要过度应用 await,例如:
- const a = await queryA(); // 等待 queryA 履行完毕后
- const b = await queryB(); // 履行 queryB
- doSomething(a, b);
这时 queryA 和 queryB 就是串行履行的。可以略作修改:
- const promiseA = queryA(); // 履行 queryA
- const b = await queryB(); // 履行 queryB 并等待其履行停止。这时同时 queryA 也在履行。
推荐阅读
今朝手机等移动设备网站开辟已经有比较好的解决筹划,一种是响应式网站,像笔者博客一样,PC网站就是移动网站,一种是把移动网站和PC网站分开,类似淘宝那样。大年夜网站搜刮引擎优化的角>>>详细阅读
本文标题:JavaScript与异步编程
地址:http://www.17bianji.com/lsqh/36197.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示