在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 如何使用Promise完成以下需求

如何使用Promise完成以下需求

f2和f3依賴于f1的結果,f4依賴于f2和f3的結果,f6依賴于f3和f4和f5的結果?
怎么寫效率最高?

    f1 
  /    \
f2      f3      f5
  \    / \     /
    f4    \   /
       \   \ / 
          f6
回答
編輯回答
兔囡囡

f5沒有依賴,所以f5執(zhí)行的越早越有利,尤其是f5響應時間>f4的時候

// 模擬下請求
const timeConsumingFunc = param=>new Promise(
  (resolve) => {
    let timeout = Math.random() * 5000;
    console.log(`task ${param} will be resolved in ${timeout}ms`);
    setTimeout(() => {
      console.log(`${param} resolved`);
      resolve(param+10);
    }, timeout);
  }
);

console.time('totalTime2');
Promise.all([(()=>{
  return timeConsumingFunc(1).then(res1 => {
    console.log(`f1 get response: ${res1}`);
    return Promise.all([timeConsumingFunc(2),timeConsumingFunc(3)]);
  }).then(([res2,res3])=>{
    console.log(`f2 get response: ${res2}`);
    console.log(`f3 get response: ${res3}`);
    return timeConsumingFunc(4);
  });
})(),timeConsumingFunc(5)]).then(([res4,res5])=>{
  console.log(`f4 get response: ${res4}`);
  console.log(`f5 get response: ${res5}`);
  return timeConsumingFunc(6);
}).then(res6=>{
  console.log(`f6 get response: ${res6}`);
  console.timeEnd('totalTime2');
});

最終時間大致=MAX{(f1 + MAX(f2,f3) + f4), f5} + f6

2017年11月28日 09:43
編輯回答
絯孑氣

……樓上的各位花式炫技。為什么要把那些依賴關系全都攪和到一起?用幾個變量代價真的那么大么?那些代碼寫出來之后還能維護么?

題主問

怎么寫效率最高?

我相信程序員的效率也算數(shù)的。

const result1 = f1();
const result2 = result1.then(f2);
const result3 = result1.then(f3);
const result4 = Promise.all([result2, result3]).then(f4);
const result5 = f5();
const result6 = Promise.all([result3, result4, result5]).then(f6);

一個依賴關系一行,看到代碼就明白誰依賴誰,而且保證能并行的都并行。依賴關系之間解耦,誰變了只需要改一行代碼。錯誤也能正常拋出。

無法忍受垃圾變量?套到塊級作用域里就行了。

let result;
{
  const result1 = f1();
  // ...
  const result6 = Promise.all([result3, result4, result5]).then(f6);
  result = result6;
}

新建塊級作用域的代價幾乎為零,新開6個變量的成本也可以忽略,換來的是可讀性的巨大提升。


評論里有同學懷疑這段代碼的正確性,所以只好創(chuàng)建fiddle來驗證一下。

https://jsfiddle.net/liqi0816...

function sleep(ms, message) {
    return new Promise(resolve => setTimeout(() => {
        // 1. 輸出點東西,這樣我們就知道進度了
        document.body.append(`${message}: ${Date()}`, document.createElement('br'));

        // 2. 然后resolve它
        resolve(message);
    }, ms));
}

const f1 = () => sleep(2000, 'f1');
const f2 = () => sleep(2000, 'f2');
const f3 = () => sleep(2000, 'f3');
const f4 = () => sleep(2000, 'f4');
const f5 = () => sleep(2000, 'f5');
const f6 = () => sleep(2000, 'f6');

const result1 = f1();
// ...
const result6 = Promise.all([result3, result4, result5]).then(f6);

result6.then(message => document.body.append(`end of excution(${message}): ${Date()}`));

結果

f1: Tue Jun 19 2018 18:00:37 GMT+0800 (中國標準時間)
f5: Tue Jun 19 2018 18:00:37 GMT+0800 (中國標準時間)
f2: Tue Jun 19 2018 18:00:39 GMT+0800 (中國標準時間)
f3: Tue Jun 19 2018 18:00:39 GMT+0800 (中國標準時間)
f4: Tue Jun 19 2018 18:00:41 GMT+0800 (中國標準時間)
f6: Tue Jun 19 2018 18:00:43 GMT+0800 (中國標準時間)
end of excution(f6): Tue Jun 19 2018 18:00:43 GMT+0800 (中國標準時間)

回答一下疑問吧

你的代碼能正確執(zhí)行????????

當然能。請不要想當然,做過實驗再懷疑。

result1執(zhí)行多次

.then沒有副作用的。可能這位同學把f1result1搞混了。f1只執(zhí)行了一次,result1包裝的是這一次執(zhí)行的結果,不論.then多少次也不會變。

2017年3月10日 02:24
編輯回答
夢囈
            let temp = f1().then(data1 => {
                return Promise.all([f2(), f3()])
            }).then(([data2, data3]) => {
                return Promise.all([f4(), Promise.resolve(data3)])
            })

            Promise.all([temp, f5()]).then(([[data4, data3], data5]) => {
                console.log(data4, data3, data5)
                return f6()
            }).catch(error=>{
                console.log(error)
            })
2017年7月23日 13:53
編輯回答
膽怯
f1().then(data1 => promise.all([f2(data1), f3(data1)]))
    .then(([data2, data3]) => promsie.all([f4({ data2, data3 }), f5()])
    .then(([data4, data5]) => f6({ data3, data4, data5 })))
    .then(data6 => console.log('結束'))
2018年6月5日 09:48