2013-02-06 79 views
3

我正在爲jQuery AJAX方法創建一個包裝器,因爲在實際進行之前,我的AJAX請求依賴於異步工作。推遲的jQuery AJAX包裝

什麼我目前做的是這樣的:http://pastie.org/private/bfdvep4kcdclzupsyddmiq

var ajax = function (options) { 
    var deferred = $.Deferred(); 

    doAsyncWork() 
    .done(function (attributes) { 
     $.ajax(options) 
     .done(function() { 
      deferred.resolve.apply(this, arguments); 
     }) 
     .fail(function() { 
      deferred.reject.apply(this, arguments); 
     }); 
    }) 
    .fail(function() { 
     deferred.reject(); 
    }); 

    return deferred.promise(); 
}; 

ajax().readyState // undefined 

它有一個外部推遲返回的承諾。我實際執行AJAX請求之前,先啓動doAsyncWork()並等待它完成。現在,雖然這起作用,但問題是當其他腳本使用包裝器時,因爲它們無法訪問jQuery XHR對象的屬性。

有沒有辦法解決這個優雅?

+0

傳遞'function(){deferred.resolve.apply(this,arguments);}'就像傳遞'deferred.resolve'一樣,但後者不需要額外的閉包。 – Alnitak

回答

2

問題是:他們爲什麼要這樣做?你是否試圖用你的包裝透明替換$.ajax()?這會很快變得複雜,因爲您必須考慮​​的所有屬性和方法。

從理論上講,這樣的事情是可能的,但我不會把它優雅不建議它:

var ajax = function (options) { 
    var deferred = $.Deferred(); 
    var promise = deferred.promise(); 

    doAsyncWork() 
    .done(function (attributes) { 
     $.ajax(options) 
     .done(function() { 
      promise.readyState = 4 
      deferred.resolve.apply(this, arguments); 
     }) 
     .fail(function() { 
      promise.readyState = 4 
      deferred.reject.apply(this, arguments); 
     }); 
    }) 
    .fail(function() { 
     deferred.reject(); 
    }); 

    promise.readyState = 0; 
    return promise; 
}; 

其他readyState的設置應該去中選取適當的回調(也就是在沒有onreadystatechange JQuery的)。

那麼,該怎麼做呢?

如果其他腳本想要使用你的包裝,他們將不得不使用延遲API。如果由於某種原因,他們真的需要訪問jqXHR對象,就可以像這樣爲它供給:

var ajax = function (options, xhrReadyCallback) { 
    var deferred = $.Deferred(); 

    doAsyncWork() 
    .done(function (attributes) { 
     var xhr = $.ajax(options) 
     .done(function() { 
      deferred.resolve.apply(this, arguments); 
     }) 
     .fail(function() { 
      deferred.reject.apply(this, arguments); 
     }); 
     xhrReadyCallback(xhr); 
    }) 
    .fail(function() { 
     deferred.reject(); 
    }); 

    return deferred.promise(); 
}; 

用法:

ajax(options, function(xhr) { 
    // now available: 
    xhr.readyState; 
}); 
+0

這是一個很好的解決方案!非常感謝。 – Morten

0

有沒有辦法直接通過jqXHR對象,因爲它不是函數返回時創建的。

但是 - 不要忘記,jqXHR 是在兩個donefail回調可,作爲第三和第一個參數分別。