2012-09-11 38 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