我有一个问题,我试图通过在javascript中使用延迟对象来解决(我不熟悉延迟对象)。
问题: 用户尝试运行一个函数(可以有很多不同的函数)。如果函数失败...它将尝试再次登录然后再试一次(一次)。如果登录失败。那么一切都失败了。
这些函数和login函数包含将返回的Ajax调用。
我的问题是: 在函数中的所有其他代码运行之后,我可以依赖于var dfd(在tryAjax函数的末尾)最后执行吗?
以下是代码:
function tryAjax(func)
{
var dfd = new jQuery.Deferred();
window[func]().then(
function(p1,p2,p3)
{
//Everything worked great. No need to login.
dfd.resolve(p1,p2,p3);
},
function()
{
//func failed
//try to login user again before trying.
loginUser().then(
function()
{
//Login success
//Try to run func again.
window[func]().then(
function(p1,p2,p3)
{
//Func succes after login
dfd.resolve(p1,p2,p3);
},
function(p1,p2,p3)
{
//Func failed after login
dfd.reject(p1,p2,p3);
});
},
function(p1,p2,p3)
{
//Login failed
dfd.reject(p1,p2,p3);
});
});
return dfd;
}
And to call it:
tryAjax('getData').then(
function(p1,p2,p3)
{
//Success
},
function(p1,p2,p3)
{
//Error
});
答案 0 :(得分:1)
所以基本上,你想按顺序执行3个延迟,并在第一次成功后停止。 我会选择像这样的通用函数:
function dfdSequence() {
var deferred = jQuery.Deferred();
var execute = function(functions) {
var promise = functions[0].apply(functions[0], args);
promise.done(function() {
deferred.resolve();
});
if (functions.length === 1) {
// It was the last call
promise.fail(function() {
deferred.reject();
});
} else {
// Fail, let's move on the next function
promise.fail(function() {
execute(functions.slice(1, functions.length));
});
}
};
execute(Array.prototype.slice.call(arguments, 0, arguments.length));
return deferred.promise();
}
该函数接受任意数量的函数并按顺序执行。基本上,每个函数都返回一个promise,如果promise被拒绝,则执行下一个函数。 使用样本:
dfdSequence(function() { // Your first login attempt return $.ajax(...); }, function() { // Your second login attempt return $.ajax(...); }, function() { // Your last login attempt return $.ajax(...); }).then(function() { /* Success! */ }, function() { /* Failure */ });
修改强> 好吧,我想我误解了这个问题。 这段代码怎么样:
function getData() { return $.ajax(...); } function loginUser() { return $.ajax(...); } var deferred = jQuery.Deferred(); getData().then(function() { // Success deferred.resolve(); }, function() { loginUser().then(function() { getData().done(function() { deferred.resolve(); }); }, function() { deferred.reject(); }); }