延迟对象的问题

时间:2012-09-11 08:22:31

标签: jquery ajax deferred

我有一个问题,我试图通过在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
});

1 个答案:

答案 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();
  });
}