Javascript 当存在大量回调时,如何在异步函数中正确返回值

Javascript 当存在大量回调时,如何在异步函数中正确返回值,javascript,node.js,asynchronous,ecmascript-6,async-await,Javascript,Node.js,Asynchronous,Ecmascript 6,Async Await,我有一个异步函数,它调用其他异步函数,当它们全部完成时,我将返回结果 我不想使用Promise.all,因为如果这些函数中的任何一个失败,我就不会将它们添加到结果中 我的代码是这样的。它可以工作,但我不喜欢newpromise,我想用ES6异步方式来做,所以callAll函数应该看起来像constcallall=async(query)=>{ const callAll = (query) => { return new Promise((resolve, reject) =>

我有一个异步函数,它调用其他异步函数,当它们全部完成时,我将返回结果

我不想使用
Promise.all
,因为如果这些函数中的任何一个失败,我就不会将它们添加到结果中

我的代码是这样的。它可以工作,但我不喜欢
newpromise
,我想用ES6异步方式来做,所以callAll函数应该看起来像
constcallall=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);
                }
            });
        });
    });
};

您可以使用
Promise。您只需缓存拒绝并将其转化为解决

函数someAsyncFunction(){
返回新承诺((解决、拒绝)=>{
setTimeout(函数(){
if(Math.round(Math.random()*100)%2){
返回解析(“某些结果”);
}
拒绝(“某些拒绝”);
})
}, 1);
}
var承诺=[];
对于(变量i=0;i<10;i++){
//这是重要的一部分
//catch块返回一个已解决的承诺
//所以现在所有的承诺都会解决
promises.push(someAsyncFunction().catch(函数(原因)){
返回原因;
}));
}
承诺。所有(承诺)。然后(功能(结果){
console.log(“所有已解决”);
控制台日志(结果);
}).catch(函数(原因){
控制台错误(‘已拒绝’);
控制台日志(原因);

})
你可以使用
承诺。你唯一需要做的就是缓存拒绝并将其转化为解决

函数someAsyncFunction(){
返回新承诺((解决、拒绝)=>{
setTimeout(函数(){
if(Math.round(Math.random()*100)%2){
返回解析(“某些结果”);
}
拒绝(“某些拒绝”);
})
}, 1);
}
var承诺=[];
对于(变量i=0;i<10;i++){
//这是重要的一部分
//catch块返回一个已解决的承诺
//所以现在所有的承诺都会解决
promises.push(someAsyncFunction().catch(函数(原因)){
返回原因;
}));
}
承诺。所有(承诺)。然后(功能(结果){
console.log(“所有已解决”);
控制台日志(结果);
}).catch(函数(原因){
控制台错误(‘已拒绝’);
控制台日志(原因);

});
您可能会将代码缩减为以下内容。您可以从
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);
};

您可能会将代码缩减为以下内容。您可以从
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);
};

您是否签出了
async
模块?它将为您节省大量人力scratching@borislemke
async.parallel
似乎不接受第一个参数上的承诺,我不想做任何奇怪的黑客操作,也不想将承诺转换为回调,我正在尝试尽可能地使代码更漂亮。您查看了
async
模块?它将为您节省大量的人力scratching@borislemke
async.parallel
似乎不接受第一个参数的承诺,我不想做任何奇怪的黑客操作,并将承诺转换为回调,我正试图使代码尽可能好!这是一个好主意,我还不打算接受它,也许有人打赌谢谢!这是个好主意,我还不打算接受,也许有人有更好的方法。实际上,它会将
未定义的
传递到结果集,不过没关系,只是希望在回答中注意到它现在开始变得有点混乱了,哈哈,但是你可以返回false,然后将它们过滤掉t将
未定义的
传递到结果集,虽然没关系,但是如果在回答中注意到它会很好,现在开始变得有点混乱了,哈哈,但是您可以返回false并将其过滤掉。