Javascript 如何等待几个HTTP承诺完成并仅在所有承诺都失败时显示模式
我在一个页面上有两个HTTP调用,它们是完全分开的Javascript 如何等待几个HTTP承诺完成并仅在所有承诺都失败时显示模式,javascript,angularjs,http,promise,Javascript,Angularjs,Http,Promise,我在一个页面上有两个HTTP调用,它们是完全分开的 vm.$onInit = function() { .... .... //Get all the items only once during initialization ds.getAllItems().then(function(result){ vm.items = result; },function(error){ vm.errorInApi = true;
vm.$onInit = function() {
....
....
//Get all the items only once during initialization
ds.getAllItems().then(function(result){
vm.items = result;
},function(error){
vm.errorInApi = true;
});
.....
.....
}
vm.getTimes = function(){
.....
.....
HttpWrapper.send(url,{"operation":'GET'}).then(function(times){
.....
}
如果两个API都失败了,那么我只需要显示一个模式
我可以将一个变量初始化为true,在API出现故障时,我可以将其设置为false,然后只显示模式
但是,那么等待所有API完成需要多长时间 你可以使用
Promise.all
首先,您应该在一个数组中获得这两个承诺。为了实现这一点,如果您的两个函数返回它们所创建的承诺,则可能会很有用:
vm.$onInit = function() {
....
....
return ds.getAllItems().then(function(result){
vm.items = result;
},function(error){
vm.errorInApi = true;
});
}
vm.getTimes = function(){
.....
.....
return HttpWrapper.send(url,{"operation":'GET'}).then(function(times){
.....
});
}
然后将根据返回值构建数组:
var arr = [];
arr.push(vm.$onInit());
...
arr.push(vm.getTimes());
您在一条注释中写道,getTimes
“在某个按钮单击时被调用”,因此您将在那里进行第二次推送
或者,也许你会看到另一种方式来获得这些承诺。。。你怎么做并不重要,只要你做到了这一点
然后(在该点击处理程序中),您需要检测两个承诺都被拒绝的情况<代码>承诺。所有都可以做到,但您需要翻转承诺结果:
// Flip promises so that a rejected one is regarded as fulfilled and vice versa:
arr = arr.map(p => p.then(res => { throw res }).catch(err => err));
// Detect that all original promises rejected, i.e. that the new promises all fulfill.
Promise.all(arr).then(function() {
// execute whatever you need to execute when both ajax calls failed
}).catch(err => err); // ignore
您可以使用
async/wait
和.catch()
来确定被拒绝的Promise
s的数量,如果该数量等于N,则执行操作,其中N是执行操作所需的被拒绝的Promise
值的数量
如@trincot所述,先决条件是从函数中返回承诺,并从传递给的函数中返回值。然后()
,然后从中抛出错误()
。catch()
或第二个参数处的函数。然后()
参见
常数N=2;
函数onInit(){
返回承诺。解决(“已解决”)
}
函数getTimes(){
返还承诺。拒绝(“拒绝”);
}
const first=onInit();
文档查询选择器(“按钮”)
.onclick=异步函数(){
设n=0;
const firstP=wait first.catch(()=>++n);
const secondP=await getTimes().catch(()=>++n);
如果(n==n){
//如果'n'等于'n',则执行操作`
}否则{
//做其他事情
console.log(n,n)
}
};代码>
单击
嗯。。。只需颠倒承诺的极性,使用Promise.all()
Promise.all()
通常会在所有承诺解决后解决,因此一旦承诺被撤销,一旦所有承诺被拒绝,它就会解决
var invert=p=>新承诺((v,x)=>p.then(x,v));
Promise.all([Promise.reject(“Error 404”)、Promise.reject(“Error WTF”)].map(倒置))
.then(v=>console.log(v))代码>调用是在同一时间进行的吗?如果两个调用同时运行,则可以使用$q.all()包装@guest271314不首先调用OnInit,然后在单击某个按钮时调用getTimes。如果两个承诺都失败,则更改为true,则可以处理变量标志并使用$watch侦听。@Jesusarrasco我认为$q.all
将无法工作,因为一旦其中一个承诺被拒绝,将立即调用带有错误的拒绝回调。“在某些按钮单击时调用getTimes“谢谢,@guest271314,我不认为这会改变我的答案,但我添加了这句话,并建议在该场景中放置代码。如果一个承诺失败,另一个承诺不执行,这将不起作用。就像StanislavKvitash说的,我的更新中没有,它从一开始就存在;-)我认为使用一些var和watch是更好的控制器,因为如果你将两个承诺连成一个,如果一个失败,另一个将不会执行,即使第一个不执行,第二个是。这并不意味着所有内容都被拒绝。“getTimes在某些按钮上被调用,单击“@guest271314 So…”?应答时的代码在哪里执行评估事件处理程序中的承诺值的任务?@guest271314一旦你知道了诀窍,这是一项微不足道的工作。。然而,我补充说。