Jon*_*Jon 210 javascript promise es6-promise
我有一个Promise数组,我正在使用Promise.all(arrayOfPromises)解析;
我接着继续承诺链.看起来像这样
existingPromiseChain = existingPromiseChain.then(function() {
var arrayOfPromises = state.routes.map(function(route){
return route.handler.promiseHandler();
});
return Promise.all(arrayOfPromises)
});
existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
// do stuff with my array of resolved promises, eventually ending with a res.send();
});
Run Code Online (Sandbox Code Playgroud)
我想添加一个catch语句来处理单个promise,以防它出错.但是当我尝试时,Promise.all返回它找到的第一个错误(忽略其余的),然后我无法从其余的数据中获取数据数组中的promise(没有错误).
我尝试过像......
existingPromiseChain = existingPromiseChain.then(function() {
var arrayOfPromises = state.routes.map(function(route){
return route.handler.promiseHandler()
.then(function(data) {
return data;
})
.catch(function(err) {
return err
});
});
return Promise.all(arrayOfPromises)
});
existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
// do stuff with my array of resolved promises, eventually ending with a res.send();
});
Run Code Online (Sandbox Code Playgroud)
但这并没有解决.
谢谢!
-
编辑:
下面的答案完全正确,代码因其他原因而破裂.如果有人有兴趣,这就是我最终得到的解决方案......
Node Express服务器链
serverSidePromiseChain
.then(function(AppRouter) {
var arrayOfPromises = state.routes.map(function(route) {
return route.async();
});
Promise.all(arrayOfPromises)
.catch(function(err) {
// log that I have an error, return the entire array;
console.log('A promise failed to resolve', err);
return arrayOfPromises;
})
.then(function(arrayOfPromises) {
// full array of resolved promises;
})
};
Run Code Online (Sandbox Code Playgroud)
API调用(route.async调用)
return async()
.then(function(result) {
// dispatch a success
return result;
})
.catch(function(err) {
// dispatch a failure and throw error
throw err;
});
Run Code Online (Sandbox Code Playgroud)
在.then之前放置.catch for Promise.all似乎是为了捕获原始promise中的任何错误,然后将整个数组返回到下一个.然后
谢谢!
jib*_*jib 155
Promise.all
是全有或全无.它会在阵列中的所有承诺解析后解析,或者在其中一个承诺拒绝后立即拒绝.换句话说,它可以使用所有已解析值的数组进行解析,也可以使用单个错误进行拒绝.
有些库有一些叫做的东西Promise.when
,据我所知,它会等待阵列中的所有承诺解析或拒绝,但我不熟悉它,而且它不在ES6中.
你的代码
我同意其他人的意见,你的修复应该有效.它应该使用可能包含成功值和错误对象的数组的数组来解析.在成功路径中传递错误对象是不寻常的,但假设您的代码期望它们,我认为没有问题.
我能想到为什么它"无法解决"的唯一原因是它没有显示我们没有向你展示的代码,以及你没有看到任何关于这个的错误消息的原因是因为这个承诺链没有终止赶上(至于你向我们展示的东西).
我冒昧地将你的例子中的"现有链"分解出来并用一个捕获来终止链.这可能不适合你,但对于阅读本文的人来说,重要的是始终返回或终止链,或者潜在的错误,甚至是编码错误,都会被隐藏(这是我怀疑在这里发生的事情):
Promise.all(state.routes.map(function(route) {
return route.handler.promiseHandler().catch(function(err) {
return err;
});
}))
.then(function(arrayOfValuesOrErrors) {
// handling of my array containing values and/or errors.
})
.catch(function(err) {
console.log(err.message); // some coding error in handling happened
});
Run Code Online (Sandbox Code Playgroud)
Sol*_*inh 105
新的答案
const results = await Promise.all(promises.map(p => p.catch(e => e)));
const validResults = results.filter(result => !(result instanceof Error));
Run Code Online (Sandbox Code Playgroud)
老答复
我们必须编写自定义Promise.all().这是我在项目中使用的解决方案.错误将作为正常结果返回.在所有承诺完成后,我们可以过滤掉错误.
const results = await Promise.all(promises.map(p => p.catch(e => e)));
const validResults = results.filter(result => !(result instanceof Error));
Run Code Online (Sandbox Code Playgroud)
Mos*_*ada 57
ES2020为Promise
类型引入了新方法:Promise.allSettled()
.
Promise.allSettled
当所有输入承诺都得到解决时,会给你一个信号,这意味着它们要么被履行,要么被拒绝。这在您不关心 Promise 的状态,只想知道工作何时完成的情况下很有用,无论它是否成功。
(async function() {
const promises = [
fetch('//api.stackexchange.com/2.2'), // succeeds
fetch('/this-will-fail') // fails
];
const result = await Promise.allSettled(promises);
console.log(result.map(promise => promise.status));
// ['fulfilled', 'rejected']
})();
Run Code Online (Sandbox Code Playgroud)
在v8 博客文章中阅读更多内容。
Ben*_*uer 19
为了继续Promise.all
循环(即使Promise拒绝),我写了一个被调用的实用函数executeAllPromises
.此实用程序函数返回带有results
和的对象errors
.
我们的想法是,你传递给的所有executeAllPromises
Promise都将被包装成一个永远解决的新Promise.新的Promise解决了一个有2个点的阵列.第一个点保存解析值(如果有的话),第二个点保留错误(如果包装的Promise拒绝).
作为最后一步,executeAllPromises
累积包装的promises的所有值,并返回带有数组的最终对象results
和数组errors
.
这是代码:
function executeAllPromises(promises) {
// Wrap all Promises in a Promise that will always "resolve"
var resolvingPromises = promises.map(function(promise) {
return new Promise(function(resolve) {
var payload = new Array(2);
promise.then(function(result) {
payload[0] = result;
})
.catch(function(error) {
payload[1] = error;
})
.then(function() {
/*
* The wrapped Promise returns an array:
* The first position in the array holds the result (if any)
* The second position in the array holds the error (if any)
*/
resolve(payload);
});
});
});
var errors = [];
var results = [];
// Execute all wrapped Promises
return Promise.all(resolvingPromises)
.then(function(items) {
items.forEach(function(payload) {
if (payload[1]) {
errors.push(payload[1]);
} else {
results.push(payload[0]);
}
});
return {
errors: errors,
results: results
};
});
}
var myPromises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.reject(new Error('3')),
Promise.resolve(4),
Promise.reject(new Error('5'))
];
executeAllPromises(myPromises).then(function(items) {
// Result
var errors = items.errors.map(function(error) {
return error.message
}).join(',');
var results = items.results.join(',');
console.log(`Executed all ${myPromises.length} Promises:`);
console.log(`— ${items.results.length} Promises were successful: ${results}`);
console.log(`— ${items.errors.length} Promises failed: ${errors}`);
});
Run Code Online (Sandbox Code Playgroud)
Kam*_*ski 12
而不是 Promise.all 使用Promise.allSettled等待所有承诺解决,无论结果如何
let p1 = new Promise(resolve => resolve("result1"));
let p2 = new Promise( (resolve,reject) => reject('some troubles') );
let p3 = new Promise(resolve => resolve("result3"));
// It returns info about each promise status and value
Promise.allSettled([p1,p2,p3]).then(result=> console.log(result));
Run Code Online (Sandbox Code Playgroud)
填充物
if (!Promise.allSettled) {
const rejectHandler = reason => ({ status: 'rejected', reason });
const resolveHandler = value => ({ status: 'fulfilled', value });
Promise.allSettled = function (promises) {
const convertedPromises = promises
.map(p => Promise.resolve(p).then(resolveHandler, rejectHandler));
return Promise.all(convertedPromises);
};
}
Run Code Online (Sandbox Code Playgroud)
小智 10
正如@jib所说,
Promise.all
是全有还是全无。
但是,您可以控制“允许”失败的某些承诺,我们希望继续进行.then
。
例如。
Promise.all([
doMustAsyncTask1,
doMustAsyncTask2,
doOptionalAsyncTask
.catch(err => {
if( /* err non-critical */) {
return
}
// if critical then fail
throw err
})
])
.then(([ mustRes1, mustRes2, optionalRes ]) => {
// proceed to work with results
})
Run Code Online (Sandbox Code Playgroud)
Using Async await -
这里,一个异步函数func1返回一个解析值,而func2在这种情况下抛出错误并返回null,我们可以按需要处理它并相应地返回。
const callingFunction = async () => {
const manyPromises = await Promise.all([func1(), func2()]);
console.log(manyPromises);
}
const func1 = async () => {
return 'func1'
}
const func2 = async () => {
try {
let x;
if (!x) throw "x value not present"
} catch(err) {
return null
}
}
callingFunction();
Run Code Online (Sandbox Code Playgroud)
输出为-['func1',null]
如果你使用q库https://github.com/kriskowal/q 它有q.allSettled()方法可以解决这个问题你可以处理每个承诺,取决于它的状态要么fullfiled还是拒绝所以
existingPromiseChain = existingPromiseChain.then(function() {
var arrayOfPromises = state.routes.map(function(route){
return route.handler.promiseHandler();
});
return q.allSettled(arrayOfPromises)
});
existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
//so here you have all your promises the fulfilled and the rejected ones
// you can check the state of each promise
arrayResolved.forEach(function(item){
if(item.state === 'fulfilled'){ // 'rejected' for rejected promises
//do somthing
} else {
// do something else
}
})
// do stuff with my array of resolved promises, eventually ending with a res.send();
});
Run Code Online (Sandbox Code Playgroud)
Asa*_*af 5
const promises = [
fetch('/api-call-1'),
fetch('/api-call-2'),
fetch('/api-call-3'),
];
// Imagine some of these requests fail, and some succeed.
const resultFilter = (result, error) => result.filter(i => i.status === (!error ? 'fulfilled' : 'rejected')).map(i => (!error ? i.value : i.reason));
const result = await Promise.allSettled(promises);
const fulfilled = resultFilter(result); // all fulfilled results
const rejected = resultFilter(result, true); // all rejected results
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
139644 次 |
最近记录: |