我有一个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();
});
我想添加一个catch语句来处理一个单独的promise,以防它出错,但是当我尝试时,promise。all返回它找到的第一个错误(忽略其余的错误),然后我就不能从数组中的其余承诺(没有错误)中获得数据。
我试过做一些像…
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();
});
但这并不能解决问题。
谢谢!
--
编辑:
下面的答案是完全正确的,代码被破坏是由于其他原因。如果有人感兴趣,这是我最终得出的解决方案……
节点快速服务器链
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;
})
};
API调用(路由。异步调用)
return async()
.then(function(result) {
// dispatch a success
return result;
})
.catch(function(err) {
// dispatch a failure and throw error
throw err;
});
把。catch作为承诺。在.then之前的所有内容似乎都用于从原始的promise中捕获任何错误,但随后将整个数组返回到下一个.then
谢谢!
在allsettle的帮助下,我们现在可以读取的状态
每个承诺都是,并单独处理每个错误,而不会丢失任何关键信息
const promises = [
fetch('/api/first'), // first
fetch('/api/second') // second
];
最简单的方法是处理错误
const [firstResult, secondResult] = await Promise.allSettled(promises)
// Process first
if (firstResult.status === 'rejected') {
const err = firstResult.reason
// Here you can handle error
} else {
const first = firstResult.value
}
// Process second
if (secondResult.status === 'rejected') {
const err = secondResult.reason
// Here you can handle error
} else {
const second = secondResult.value
}
处理错误的好方法
const results = await Promise.allSettled(promises);
const [first, second] = handleResults(results)
function handleResults(results) {
const errors = results.filter(result => result.status === 'rejected').map(result => result.reason)
if (errors.length) {
// Aggregate all errors into one
throw new AggregateError(errors)
}
return results.map(result => result.value)
}
继续承诺。我写了一个名为executeAllPromises的实用函数。这个实用函数返回一个带有结果和错误的对象。
其思想是,传递给executeAllPromises的所有Promise都将被包装成一个新的Promise,该Promise将始终解决。新的Promise解析了一个有2个点的数组。第一个点保存解析值(如果有的话),第二个点保留错误(如果包装的Promise拒绝)。
作为最后一步,executeAllPromises会累积包装的promise的所有值,并返回带有结果数组和错误数组的最终对象。
代码如下:
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}`);
});
你考虑过Promise.prototype.finally()吗?
它的设计似乎完全是为了做你想做的事情——一旦所有的承诺都解决了(解决/拒绝),就执行一个函数,而不管其中一些承诺是否被拒绝。
来自MDN文档:
如果您希望在承诺确定之后进行一些处理或清理,而不管其结果如何,那么finally()方法可能很有用。
finally()方法非常类似于调用.then(onFinally, onFinally),但是有一些区别:
在内联创建函数时,可以传递一次,而不是被迫声明两次,或者为它创建一个变量。
finally回调将不会接收任何参数,因为没有可靠的方法来确定承诺是否被实现或拒绝。当您不关心被拒绝的原因或实现价值时,这个用例恰好适用,因此不需要提供它。
与Promise.resolve(2).then(() =>{},() =>{})(将被未定义解析)不同,Promise.resolve(2).finally(() =>{})将被2解析。
类似地,与Promise.reject(3).then(() =>{},() =>{})(将用undefined实现)不同,Promise.reject(3).finally(() =>{})将被3拒绝。
==后退==
如果你的JavaScript版本不支持Promise.prototype.finally(),你可以使用Jake Archibald的这个变通方法:Map (p => p.catch(() => undefined)));