在前面的系列文章中,对脚步语言程序中用原生方式和Promise对象实现异步操作分别作出了各自解释与说明,通过上面两篇文章说明可以看出用Promise对象方法更简单。想了解脚步原生方式实现异步操作,请点击 这里 进入查看;而想了解Promise对象实行异步操作,请点击 这里 进入查看。
此外,后续文章中,还继续描述了“Promise对象的then链的用法”和“async和await函数的作用”,请分别点击 前者 和 后者 进入查看各自的用法或作用。通过前面的两篇文章看出,感觉then链和async/await函数的作用差不多,尤其对于单一的then链实现来说,很难看出async/await函数方式有什么优势出来。
实际上,推出Promise及其then链是为了解决多层次的回调函数问题的,而async/await函数是为了简化多个then链情况而出现的。换言之,当一个业务同时由几个事务链构成时候,势必需要构建多个then链来对应实现。
下面依然分别给出各自的代码示例,从而直观地来说两者之间的区别与联系,依旧用SetTimeout模拟异步操作。下面案例场景是讲一个业务场景由三个流程组成,依次执行,每个流程所需时间是前一个流程基础上增加500毫秒。
一、多个的then链
示例代码:
let totalTime = 0;
function complete(num) {
totalTime = totalTime+num;
return new Promise(resolve => {
setTimeout(() => resolve(num + 500), (num + 500));
});
}
function process1(num) {
console.log(`process1 execution needed for ${num} milliseconds`);
return complete(num);
}
function process2(num) {
console.log(`process2 execution needed for ${num} milliseconds`);
return complete(num);
}
function process3(num) {
console.log(`process3 execution needed for ${num} milliseconds`);
return complete(num);
}
function byThenChain() {
console.time("byThenChain");
const time1 = 500;
process1(time1)
.then(time2 => process2(time2))
.then(time3 => process3(time3))
.then(result => {
console.log(`business process spends totally ${totalTime} milliseconds`);
console.timeEnd("byThenChain");
});
}
byThenChain();
输出结果:
process1 execution needed for 500 milliseconds
process2 execution needed for 1000 milliseconds
process3 execution needed for 1500 milliseconds
business process spends totally 3000 milliseconds
byThenChain:4513 毫秒 - 倒计时结束
二、多个的async/await函数
示例代码:
let totalTime = 0;
function complete(num) {
totalTime = totalTime+num;
return new Promise(resolve => {
setTimeout(() => resolve(num + 500), (num + 500));
});
}
function process1(num) {
console.log(`process1 execution needed for ${num} milliseconds`);
return complete(num);
}
function process2(num) {
console.log(`process2 execution needed for ${num} milliseconds`);
return complete(num);
}
function process3(num) {
console.log(`process3 execution needed for ${num} milliseconds`);
return complete(num);
}
async function byThenChain() {
console.time("byThenChain");
const time1 = 500;
const time2 = await process1(time1);
const time3 = await process2(time2);
const result = await process3(time3);
console.log(`business process spends totally ${totalTime} milliseconds`);
console.timeEnd("byThenChain");
}
byThenChain();
输出结果:
process1 execution needed for 500 milliseconds
process2 execution needed for 1000 milliseconds
process3 execution needed for 1500 milliseconds
business process spends totally 3000 milliseconds
byThenChain:4507 毫秒 - 倒计时结束
好啦,结果是一样的,但两者的代码简洁且可读性做个比较,显然async/await函数的代码更简单,异步操作代码跟写同步代码差不多,但是差异是不是还不是特别明显的,对吧。
在刚才业务场景基础上,继续增加复杂度,即后一个业务流程依赖于前面的所有业务流程所需时间,两者实现代码又是如何呢?
一、多个的then链
示例代码:
let totalTime = 0;
function complete(num) {
totalTime = totalTime+num;
return new Promise(resolve => {
setTimeout(() => resolve(num + 500), (num + 500));
});
}
function process1(num1) {
const num = num1;
console.log(`process1 execution needed for ${num} milliseconds`);
return complete(num);
}
function process2(num1,num2) {
const num = num1+num2;
console.log(`process2 execution needed for ${num} milliseconds`);
return complete(num);
}
function process3(num1,num2,num3) {
const num = num1+num2+num3;
console.log(`process3 execution needed for ${num} milliseconds`);
return complete(num);
}
function byThenChain() {
console.time("byThenChain");
const time1 = 500;
process1(time1)
.then(time2 => {
return process2(time1,time2).then(time3 => [time1, time2, time3]);
})
.then(times => {
const [time1, time2, time3] = times;
return process3(time1,time2,time3);})
.then(result => {
console.log(`business process spends totally ${totalTime} milliseconds`);
console.timeEnd("byThenChain");
});
}
byThenChain();
输出结果:
process1 execution needed for 500 milliseconds
process2 execution needed for 1500 milliseconds
process3 execution needed for 3500 milliseconds
business process spends totally 5500 milliseconds
byThenChain:7010 毫秒 - 倒计时结束
二、多个的async/await函数
示例代码:
let totalTime = 0;
function complete(num) {
totalTime = totalTime+num;
return new Promise(resolve => {
setTimeout(() => resolve(num + 500), (num + 500));
});
}
function process1(num1) {
const num = num1;
console.log(`process1 execution needed for ${num} milliseconds`);
return complete(num);
}
function process2(num1,num2) {
const num = num1+num2;
console.log(`process2 execution needed for ${num} milliseconds`);
return complete(num);
}
function process3(num1,num2,num3) {
const num = num1+num2+num3;
console.log(`process3 execution needed for ${num} milliseconds`);
return complete(num);
}
async function byThenChain() {
console.time("byThenChain");
const time1 = 500;
const time2 = await process1(time1);
const time3 = await process2(time1,time2);
const result = await process3(time1,time2,time3);
console.log(`business process spends totally ${totalTime} milliseconds`);
console.timeEnd("byThenChain");
}
byThenChain();
输出结果:
process1 execution needed for 500 milliseconds
process2 execution needed for 1500 milliseconds
process3 execution needed for 3500 milliseconds
business process spends totally 5500 milliseconds
byThenChain:7009 毫秒 - 倒计时结束
哈哈,这会应该非常明显地看出async/await函数的优势吧,在复杂传参数情况下then链是非常麻烦的,代码维护起来相当的困难,而且很容易出错。
原文来自码嗨路书。