2017-06-01 82 views
0

我有一個異步函數,調用了其他異步函數,當它們全部完成時,我返回結果。如何在異步函數中有很多回調時正確返回值

我不想使用Promise.all,因爲如果這些功能失敗,我只是不會將它們添加到我的結果中。

ATM我的代碼看起來像這樣。它的工作原理,但我不喜歡new Promise,我想在ES6異步的方式做到這一點,所以callAll功能應該像const callAll = async (query) => {

const callAll = (query) => { 
    return new Promise((resolve, reject) => { 
     const results = []; 

     const jobs = [ 
      { 
       promise: someModuleFirst.search(query), 
       done: false 
      }, 
      { 
       promise: someModuleSecond.search(query), 
       done: false 
      }, 
      { 
       promise: someModuleThird.search(query), 
       done: false  
      } 
     ]; 

     const areAllDone =() => { 
      if(!jobs.filter((job) => !job.done).length) { 
       return true; 
      } 
     }; 

     jobs.forEach((job) => { 
      job.promise.then((result) => { 
       job.done = true; 

       results.push(result); 

       if(areAllDone()) { 
        resolve(results); 
       } 
      }).catch((error) => { 
       job.done = true; 

       if(areAllDone()) { 
        resolve(results); 
       } 
      }); 
     }); 
    }); 
}; 
+0

你檢查過'async'模塊嗎?它會爲您節省大量的頭部劃傷 – borislemke

+0

@borislemke async.parallel似乎並不接受承諾在第一次參數,我不想做任何奇怪的黑客,並將承諾轉換爲回調,我試圖使代碼儘可能好 – xerq

回答

1

你可以你的代碼可能降低到以下。您可以從catch處理程序返回false,然後過濾掉不會傳遞到結果集中的數據。

const callAll = async (query) => { 
    const modules = [someModuleFirst, someModuleSecond, someModuleThird]; 
    const jobs = modules.map((module) => module.search(query).catch(() => false); 
    const results = await Promise.all(jobs); 
    return results.filter(Boolean); 
}; 
+0

啊,我應該學習如何閱讀。 :) –

+0

實際上,它會將undefined傳遞給結果集,但沒關係,只要在回答中記下它就好了 – xerq

+2

現在開始有點混亂哈哈,但是你可以返回false並且只是過濾「那些。 –

1

您可以使用Promise.all你需要做的唯一的事情就是緩存拒絕並將其轉化爲解決方案。

function someAsyncFunction() { 
 
\t return new Promise((resolve, reject) => { 
 
\t \t setTimeout(function() { 
 
\t \t \t if (Math.round(Math.random() * 100) % 2) { 
 
\t \t \t \t return resolve('some result'); 
 
\t \t \t } 
 
\t \t \t reject('some rejection'); 
 
\t \t }) 
 
\t }, 1); 
 
} 
 
var promises = []; 
 
for (var i = 0; i < 10; i++) { 
 
    // this is important part 
 
    // catch block returns a promise with is resolved 
 
    // so all promises now will resolve 
 
\t promises.push(someAsyncFunction().catch(function (reason) { 
 
\t \t return reason; 
 
\t })); 
 
} 
 
Promise.all(promises).then(function (results) { 
 
    console.log('All resolved'); 
 
\t console.log(results); 
 
}).catch(function (reason) { 
 
\t console.error('Rejected'); 
 
\t console.log(reason); 
 
});

所以你的情況,你需要改變someModuleFirst.search(query)到一些這樣的事someModuleFirst.search(query).catch(e => e)

+0

謝謝!這是一個好主意,我不會接受它,但也許有人有更好的方法 – xerq