假设我有一组promise正在发出网络请求,其中一个将失败:
// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]
Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed
假设我想要等到所有这些都完成,不管是否有一个失败了。可能有一个资源的网络错误,我可以没有,但如果我能得到,我想在继续之前。我想优雅地处理网络故障。
因为承诺。所有这些都没有留下任何空间,在不使用承诺库的情况下,处理这个问题的推荐模式是什么?
与其拒绝,不如用一个对象来解决。
当你实现承诺时,你可以这样做
Const promise = arg => {
返回新的承诺((resolve, reject) => {
setTimeout(() => {
尝试{
If (arg != 2)
返回解析({success: true, data: arg});
其他的
抛出新的错误(arg)
}捕捉(e) {
返回解析({success: false, error: e, data: arg})
}
}, 1000);
})
}
Promise.all([1、2、3、4、5)。Map (e => promise(e)))。然后(d => console.log(d))
你可以通过同步执行器nsynjs按顺序执行你的逻辑。它将在每个承诺上暂停,等待解析/拒绝,并将解析的结果分配给data属性,或者抛出异常(用于处理您将需要try/catch块)。这里有一个例子:
function synchronousCode() {
function myFetch(url) {
try {
return window.fetch(url).data;
}
catch (e) {
return {status: 'failed:'+e};
};
};
var arr=[
myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
];
console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
};
nsynjs.run(synchronousCode,{},function(){
console.log('done');
});
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>
有一个完成的提议,一个函数,可以完成这个本机,在香草Javascript:承诺。allsettle已经进入了第4阶段,在ES2020中正式发布,并在所有现代环境中实现。它和另一个答案中的反射函数很相似。这里有一个例子,来自提案页面。以前,你必须这样做:
function reflect(promise) {
return promise.then(
(v) => {
return { status: 'fulfilled', value: v };
},
(error) => {
return { status: 'rejected', reason: error };
}
);
}
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ];
const results = await Promise.all(promises.map(reflect));
const successfulPromises = results.filter(p => p.status === 'fulfilled');
使用的承诺。取而代之的是,上述内容将等价于:
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ];
const results = await Promise.allSettled(promises);
const successfulPromises = results.filter(p => p.status === 'fulfilled');
那些使用现代环境的人不需要任何库就可以使用这种方法。在这些情况下,下面的代码段应该可以正常运行:
Promise.allSettled ([
Promise.resolve (' a '),
Promise.reject (b)
])
不要犹豫(console.log);
输出:
[
{
"status": "fulfilled",
"value": "a"
},
{
"status": "rejected",
"reason": "b"
}
]
对于较老的浏览器,这里有一个符合规范的填充。