返回一个用备份承诺加强的新承诺
Returning a new promise reinforced with backup promises
我是 promises 的新手,所以我可能遗漏了一些明显的东西。我想要一个以 'promise creators' 列表作为参数和 returns 单个承诺的函数,它要么解决列表中第一个成功的承诺,要么拒绝一些一般性错误。这将用于从网站加载数据,我有几种后备方法以防一种或多种方法失败。
这是我的意思的一个工作示例。有 3 个承诺,m1
、m2
和 m3
,要么成功,要么失败。 tryAll
将尝试每一个,直到其中一个(m3
在这种情况下)解决,它被传递给初始承诺请求的 then
语句。如果要解析 m2
而不是 m3
,则永远不会尝试 m3
。
function m1(){
return new Promise(function(resolve, reject){
reject(new Error("Failed 1"));
});
}
function m2(){
return new Promise(function(resolve, reject){
reject(new Error("Failed 2"));
});
}
function m3(){
return new Promise(function(resolve, reject){
resolve("Succeeded 3");
});
}
function tryAll(methods){
return new Promise(function(resolve, reject){
if(methods.length == 0){
reject(new Error("None worked"));
}else{
methods[0]()
.then(function(data){
resolve(data);
})
.catch(function(err){
methods.shift(); // discard the first since it was already tested
tryAll(methods)
.then(function(data){
resolve(data);
})
.catch(function(err){
reject(err);
})
})
}
});
}
tryAll([m1, m2, m3])
.then(function(data){
console.log(data);
})
.catch(function(err){
console.log("failed");
})
有什么方法可以简化 tryAll
?或者有什么内置的方法可以让我完成同样的事情吗?
您可以只使用链接而不是 return 新的承诺。例如:
function tryAll(methods) {
if (methods.length === 0) {
return Promise.reject('None worked');
}
return methods[0]().catch(err => tryAll(methods.slice(1)));
}
tryAll 的 returned promise 可以是方法 [0] 的解析值,或者递归 tryAll 调用的解析值,或者 tryAll 递归最终 运行 的拒绝方法数。
为了迭代地演示这一点,您可以这样做:
function tryAll(methods) {
return methods.reduce((promise,method) => promise.catch(err => method()), Promise.reject('No methods supplied'));
}
这也会 return 相同的承诺链(尽管在这种情况下,如果 none 失败,它实际上会拒绝最后一个方法错误)
我是 promises 的新手,所以我可能遗漏了一些明显的东西。我想要一个以 'promise creators' 列表作为参数和 returns 单个承诺的函数,它要么解决列表中第一个成功的承诺,要么拒绝一些一般性错误。这将用于从网站加载数据,我有几种后备方法以防一种或多种方法失败。
这是我的意思的一个工作示例。有 3 个承诺,m1
、m2
和 m3
,要么成功,要么失败。 tryAll
将尝试每一个,直到其中一个(m3
在这种情况下)解决,它被传递给初始承诺请求的 then
语句。如果要解析 m2
而不是 m3
,则永远不会尝试 m3
。
function m1(){
return new Promise(function(resolve, reject){
reject(new Error("Failed 1"));
});
}
function m2(){
return new Promise(function(resolve, reject){
reject(new Error("Failed 2"));
});
}
function m3(){
return new Promise(function(resolve, reject){
resolve("Succeeded 3");
});
}
function tryAll(methods){
return new Promise(function(resolve, reject){
if(methods.length == 0){
reject(new Error("None worked"));
}else{
methods[0]()
.then(function(data){
resolve(data);
})
.catch(function(err){
methods.shift(); // discard the first since it was already tested
tryAll(methods)
.then(function(data){
resolve(data);
})
.catch(function(err){
reject(err);
})
})
}
});
}
tryAll([m1, m2, m3])
.then(function(data){
console.log(data);
})
.catch(function(err){
console.log("failed");
})
有什么方法可以简化 tryAll
?或者有什么内置的方法可以让我完成同样的事情吗?
您可以只使用链接而不是 return 新的承诺。例如:
function tryAll(methods) {
if (methods.length === 0) {
return Promise.reject('None worked');
}
return methods[0]().catch(err => tryAll(methods.slice(1)));
}
tryAll 的 returned promise 可以是方法 [0] 的解析值,或者递归 tryAll 调用的解析值,或者 tryAll 递归最终 运行 的拒绝方法数。
为了迭代地演示这一点,您可以这样做:
function tryAll(methods) {
return methods.reduce((promise,method) => promise.catch(err => method()), Promise.reject('No methods supplied'));
}
这也会 return 相同的承诺链(尽管在这种情况下,如果 none 失败,它实际上会拒绝最后一个方法错误)