延迟对象的问题

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

所以基本上,你想按顺序执行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(){
   //首次登录尝试
   return $ .ajax(...);
 },function(){
   //第二次登录尝试
   return $ .ajax(...);
 },function(){
   //您上次登录尝试
   return $ .ajax(...);
 })。then(function(){/ * Success!* /},function(){/ * Failure * /});

编辑:嗯,我想我误解了这个问题。 这段代码怎么样:

 function getData(){
   return $ .ajax(...);
 }
 function loginUser(){
   return $ .ajax(...);
 }
 var deferred = jQuery.Deferred();
 getData()。then(function(){
   //成功
   deferred.resolve();
 },function(){
   loginUser()。then(function(){
     getData()。done(function(){
       deferred.resolve();
     });
   },function(){
     deferred.reject();
   });
 }