根据AngularJS validation and promises的建议,我想链接确认对话框,从而立即验证几个步骤。
根据用户提供的数据,进行API调用以查看用户需要确认的所有内容。 对于需要确认的每个步骤,提示用户并让他们决定是否进入下一步。 如果任何步骤返回false,则整个链应返回false。
我一直在阅读很多关于异步JS和承诺的内容,但我不得不承认我还是比较新的。 如何正确链接这些以获得所有步骤的最终真/假?请注意,需要API调用来确定所有需要根据提供的信息向用户显示的内容,因此fetchSomeData()作为链中的第一个调用。
非常感谢任何帮助或建议。
fetchSomeData = function() {
var deferred = $q.defer();
api.fetchData(param1, param2, param3)
.then(function(data) {
deferred.resolve(data.content);
}, api.errorHandler);
return deferred.promise;
}
// data = {condition1: false, condition2: true, condition3: true}
// display confirmation dialogs for step 2 and step 3, not step 1
confirmStep1 = function(data) {
if (data.condition1) {
return confirmDialogService.popConfirm('step1').then(function(confirmed) {
return confirmed;
}, function() {
return false;
});
} else {
return $q.when(true);
}
}
confirmStep2 = function(data) {
if (data.condition2) {
return confirmDialogService.popConfirm('step2').then(function(confirmed) {
return confirmed;
}, function() {
return false;
});
} else {
return $q.when(true);
}
}
confirmStep3 = function(data) {
if (data.condition3) {
return confirmDialogService.popConfirm('step3').then(function(confirmed) {
return confirmed;
}, function() {
return false;
});
} else {
return $q.when(true);
}
}
confirmSteps = function() {
return fetchSomeData()
.then(confirmStep1(data))
.then(confirmStep2(data))
.then(confirmStep3(data));
}
confirmSteps().then(function(allConfirmed) {
if (allConfirmed == true) {
doSomething();
} else {
return;
}
});
答案 0 :(得分:1)
dfsq开始写一个答案,但删除了他的祝福,我正在添加我的看法:
confirmSteps = function() {
return fetchSomeData()
.then(confirmStep1(data))
.then(confirmStep2(data))
.then(confirmStep3(data));
}
这调用函数,它与setTimeout(alert("Hi"),5)
相同,你不想调用你想要链接它们的函数。像setTimeout(function(){ alert("Hi"); }, 5)
;
confirmSteps = function() {
return fetchSomeData()
.then(confirmStep1)
.then(confirmStep2)
.then(confirmStep3);
}
但是,这会将data
传递给第一个承诺,而前一个承诺的结果会传递给下一个承诺,而不是将data
传递给所有三个,你可以通过neting一个级别:
confirmSteps = function() {
return fetchSomeData().then(function(data){
var v1, v2;
return confirmStep1(data).then(function(d){
v1 = d;
return confirmStep2(data);
}).then(function(d){
v2 = d;
return confirmStep3(data);
}).then(function(v3){
return v1 && v2 && v3;
})
});
};
这有效,但它有点苛刻,相反,你可以使用短路 - 有点像&&
如果它是假的,只评估左手边。此外,我们可以在中心位置进行所有错误处理。这会使您的代码看起来像。
confirmStep1 = function(data) {
if (data.condition1) return $q.when(true);
return confirmDialogService.popConfirm('step1');
};
confirmStep2 = function(data) {
if (data.condition2) return $q.when(true);
return confirmDialogService.popConfirm('step2');
};
confirmStep3 = function(data) {
if (data.condition3) return $q.when(true);
return confirmDialogService.popConfirm('step3'):
};
confirmSteps = function() {
var data = fetchSomeData();
return data.then(confirmStep1).then(function(soFar){
if(!soFar) return false;
return data.then(confirmStep2);
}).then(function(soFar){
if(!soFar) return false;
return data.then(confirmStep3);
}).catch(function(){ return false; });
};
作为额外提示:
fetchSomeData = function() {
var deferred = $q.defer();
api.fetchData(param1, param2, param3)
.then(function(data) {
deferred.resolve(data.content);
}, api.errorHandler);
return deferred.promise;
};
可以简单地成为:
fetchSomeData = function() {
return api.fetchData(param1, param2, param3).then(function(data) {
return data.content;
}, api.errorHandler);
};