2017-06-01 65 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