小明是个菜鸟程序员,他写了三个延时1秒执行的函数 fn1, fn2, fn3:
var fn1 = function () {
setTimeout(function () {
console.log('fn1 is executed');
}, 1000);
};
var fn2 = function () {
setTimeout(function () {
console.log('fn2 is executed');
}, 1000);
};
var fn3 = function () {
setTimeout(function () {
console.log('fn3 is executed');
}, 1000);
};
并且希望他们按照顺序一个一个执行。
小明问: 可以写成这样吗?
(function seq(fn1, fn2, fn3) {
fn1();
fn2();
fn3();
})(fn1, fn2, fn3);
当然不行了. 主进程看到延时函数会把它们添加到主进程尾端的时间队列中。延时一秒后,3个回调函数随即执行。所以结果是一起出来的。
可是小明说: 我很任性,我就是希望按照这种思路写,直观简单,不行吗?否则我就不做码农了。
好好好,算你狠,只好给你一个装备,让你装逼下了。
这就是 async function了。
不过在执行之前,我们需要稍微改动下我们之前的fn1, fn2, fn3。
因为asyn function 如果不用promise对象就没啥意义了。
改写如下:
var fn1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
console.log('fn1 is executed');
}, 1000);
});
};
var fn2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('fn2 is executed');
resolve();
}, 1000);
});
};
var fn3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('fn3 is executed');
resolve();
}, 1000);
});
};
小明说:这种改写我还能接受,别给我整得太复杂就好。
好了,让我们来执行他们把:
(async function seq(fn1, fn2, fn3) {
await fn1();
await fn1();
await fn1();
})(fn1, fn2, fn3);
结果如下:
fn1 is executed
fn2 is executed
fn3 is executed
这三条分别按照时间顺序一秒一秒的执行。
小明很高兴: 看来只要在执行的主函数里面加一个async 和一个await就好了啊!看来学编程就是这么的so easy!
可是小明又有问题了: 如果我要执行的不是3个函数,而是30个函数怎么办,难道我要写30个await吗,那手好酸。还有啊, 执行完毕以后能不能告诉我下,否则我怎么知道执行了多少个以后是完全结束呢?
小明真是会偷懒的孩子,不过没关系,我们改写下执行的主函数:
(async function seq(...arr) {
for (let value of arr) {
await value();
}
return 'done';
})(fn1, fn2, fn3).then(function(value ){
console.log(value);
});
结果如下:
fn1 is executed
fn2 is executed
fn3 is executed
done
我们来总结下:
- 把需要执行的函数改写成可以返回的promise对象。
- 用async await 改写下普通函数。
- 用展开表达式让async function 接受任意数量的参数。
- 用 for … of 循环,遍历每个await返回的函数。
- 当所有await全部完成以后,return一个值 ,这里写的是’done’, 这个值会被then捕获到并且进行后续操作。因为return的仍然是一个promise对象。
OK, 现在大家知道小明为什么喜欢用 async function了吧?