先上代码
大众代码
function getData(data, time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(data);
}, time)
})
}
let results = [];
let startTime = new Date();
laucher();
代码段一
async function laucher() {
let dataA = await getData('a', 2000);
results.push(`${dataA}在${new Date() - startTime}毫秒放入`);
let dataB = await getData('b', 3000);
results.push(`${dataB}在${new Date() - startTime}毫秒放入`);
let dataC = await getData('c', 1000);
results.push(`${dataC}在${new Date() - startTime}毫秒放入`);
console.log(results, `输出时刻${new Date() - startTime}毫秒`);
}
输出
["a在2002毫秒放入", "b在5004毫秒放入", "c在6006毫秒放入"] "输出时刻6006毫秒"
代码段二
async function laucher() {
let dataAPromise = getData('a', 2000);
let dataBPromise = getData('b', 3000);
let dataCPromise = getData('c', 1000);
let promises = [dataAPromise, dataBPromise, dataCPromise];
results = await Promise.all(promises);
console.log(results, `输出时刻${new Date() - startTime}毫秒`);
}
输出
["a", "b", "c"] "输出时刻3006毫秒"
代码段三
async function laucher() {
let dataAPromise = getData('a', 2000);
let dataBPromise = getData('b', 3000);
let dataCPromise = getData('c', 1000);
dataA = await dataAPromise;
results.push(`${dataA}在${new Date() - startTime}毫秒放入`);
dataB = await dataBPromise;
results.push(`${dataB}在${new Date() - startTime}毫秒放入`);
dataC = await dataCPromise;
results.push(`${dataC}在${new Date() - startTime}毫秒放入`);
console.log(results, `输出时刻${new Date() - startTime}毫秒`);
}
输出
["a在2003毫秒放入", "b在3001毫秒放入", "c在3001毫秒放入"] "输出时刻3002毫秒"
代码段四
async function laucher() {
let dataAPromise = getData('a', 2000);
let dataBPromise = getData('b', 3000);
let dataCPromise = getData('c', 1000);
(async () => {
dataA = await dataAPromise;
results.push(`${dataA}在${new Date() - startTime}毫秒放入`);
})();
(async () => {
dataB = await dataBPromise;
results.push(`${dataB}在${new Date() - startTime}毫秒放入`);
console.log(results, `输出时刻${new Date() - startTime}毫秒`);//results放在末了返回的要求中
})();
(async () => {
dataC = await dataCPromise;
results.push(`${dataC}在${new Date() - startTime}毫秒放入`);
})();
}
输出
["c在1002毫秒放入", "a在2002毫秒放入", "b在3003毫秒放入"] "输出时刻3003毫秒"
总结
运用setTimeout模拟了3条异步要求,离别2000,3000,1000毫秒后返回’a’, ‘b’, ‘c’,
第一种要领很好明白,就是一步一步实行,这类要领合适要求参数依靠上一个要求返回值的状况,在这里是不存在这类关联的,也就是这类要领在这里效力是比较低的。
第二种要领一最先就提议了3个要求,并守候3要求都抵达后猎取数据。
第三种要领也一最先就提议了3个要求,并在要求抵达后顺次实行,由于a要求抵达时刻是2秒,a要求抵达后,把a的结果推入results,再往下实行,b要求是3秒,b要求迟a要求一秒抵达,也就是再过一秒后把b的结果推入results,,c的要求是1秒,这个时刻c早已抵达,在这轮轮回末端能够立即把c推入。a要求返回的数据2秒后就可以操纵了,这类要领比第二种要领能够更快处置惩罚数据。如果要求时刻是顺次递减的,那末和要领二结果是一样,在有多个要求时这类状况平常不存在。
第四种要领和第三种要领的区分是最早抵达的要求最快放入结果集,也就是我不必列队守候处置惩罚,哪一个数据先返回我就先处置惩罚哪一个数据,如果c要求返回的数据需要花比较长的时刻处置惩罚,我在一秒后就可以最先处置惩罚了,然则第三种要领我得3秒后才最先处置惩罚。能够看到我把results的输出放在了b要求抵达的函数中,由于results在末了一个要求抵达后才完全输出,与要领三的区分是猎取结果的操纵也是异步的,这个很症结,也是和要领三最大的区分,经由过程在外层包装一个自实行函数,能够防备await的操纵权跳出laucher外部,从而并发提议3个猎取结果的操纵。能够人人会有疑问如果我不清楚哪一个要求末了抵达,那怎样猎取末了的results值,这类状况能够在外面包一个Promise.all,能够细致看一下下面两个函数的区分
async function laucher() {
let dataAPromise = getData('a', 2000);
let dataBPromise = getData('b', 3000);
let dataCPromise = getData('c', 1000);
let promises = [dataAPromise, dataBPromise, dataCPromise];
results = await Promise.all(promises);
console.log(results, `输出时刻${new Date() - startTime}毫秒`);
}
输出
["a", "b", "c"] "输出时刻3003毫秒"
async function laucher() {
let dataAPromise = getData('a', 2000);
let dataBPromise = getData('b', 3000);
let dataCPromise = getData('c', 1000);
let promises = [dataAPromise, dataBPromise, dataCPromise];
results = await Promise.all(promises.map(async function (promise) {
let data = await promise;
console.log(`${data}在${new Date() - startTime}毫秒输出`);
//这里能够提早处置惩罚数据
return data
}));
console.log(results);
}
输出
c在1002毫秒输出
a在2003毫秒输出
b在3003毫秒输出
["a", "b", "c"] "输出时刻3004毫秒"
如果要求之间不存在继发关联,而且要求抵达后要实行一些运算,那末按效力来讲
要领4 > 要领3 > 要领2 > 要领1
每种要领都对应一种加载的战略,以一个运用场景来讲明一下,向背景加载页面组件(假定组件个数是3)
实行流程:
要领一: 提议组件1的要求 -> 组件1数据抵达后衬着组件1 -> 提议组件2的要求 -> 组件2数据抵达后衬着组件2 -> 提议组件3的要求 -> 组件3数据抵达后衬着组件3
要领二: 同时提议组件1,2,3的要求 -> 组件1,2,3的数据都抵达后衬着组件1,2,3
要领三: 同时提议组件1,2,3的要求 -> 组件1数据抵达后衬着组件1 -> 组件2数据抵达后衬着组件2 -> 组件3数据抵达后衬着组件3
要领四: 同时提议组件1,2,3的要求 -> 最快抵达的组件数据抵达后衬着最快抵达的组件 -> 第二快抵达的组件数据抵达后衬着第二快抵达的组件 -> 最慢抵达的组件数据抵达后衬着最慢抵达的组件
针对以上场景能够看出要领四能够让我们的页面最快衬着出内容
末了
能够看出虽然引入async/await,能够让你的代码很精简,然则async/await自身的实行流程倒是很庞杂的,下面的代码你能够猜一下输出结果(补充一点:有的文章会指出forEach函数不能放入异步操纵,这类结论是毛病的,如果是继发关联确切不适宜用forEach,但不能示意不能放入异步操纵,反而这类操纵能进步猎取数据的效力)
[1, 2].forEach(async function (value) {
console.log(value);
await console.log('a');
console.log('c');
await console.log('d');
console.log('e');
})
console.log(3);