async/await 真不是你设想中那末简朴

先上代码

大众代码

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);
    原文作者:changli
    原文地址: https://segmentfault.com/a/1190000013287938
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞