2012-09-11 37 views
0

我有一个问题,我试图解决在JavaScript中使用延期对象(我是新的延期对象)。延期对象的问题

问题: 用户试图运行一个函数(可以是很多不同的函数)。如果功能失败...它会尝试再次登录,然后重试(一次)。如果登录失败。那么所有失败。

这些函数和登录函数包含一个将被返回的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

所以基本上,你要执行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(); 
} 

这个函数的功能的任意数量和顺序执行它们。基本上,每个函数都返回一个承诺,如果承诺被拒绝,则执行下一个函数。 用法示例:

 
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(); 
    }); 
} 
+0

“所以基本上,你想执行3顺序延期,并在第一次成功后停止”。 这取决于。逻辑是,函数调用是运行一个Ajax函数并返回的通用函数(在本例中为getData()。如果这样,一切都应该结束,如果失败,它会尝试调用loginUser()函数(会尝试登录用户),如果该函数失败......全部失败,如果有效,第一个尝试失败的函数(在这种情况下,getData())将再次运行,如果失败了。如果它工作...那么一切都很好 – Juw

+0

谢谢你的回答,并花时间在原始文章中,你写了与我完全相同的代码,只有我在函数中使用它并使用窗口[func]()能够调用任何函数(返回一个待处理的ajax延迟对象)。但是这引发了一个问题。我可以依靠dfd在主代码和延期完成后返回。 。检查出我提出的这个简化函数: http://stackoverflow.com/questions/12386728/deferre d-对象返回-IT-被拒绝的前 - -或分辨 – Juw