簡體   English   中英

VanillaJS Promise實現替換jQuery notify / progress事件

[英]VanillaJS Promise implementation to replace jQuery notify/progress event

我目前正在使用$.Deferred()對象發布消息。

當服務器返回錯誤時,我正在使用notify ,然后重試,直到成功或失敗X次。

我想刪除jQuery的用法,並轉到與ES6相關的選項。

我知道如何使用Promise() ,但是它可以被拒絕或解決,但不能同時被拒絕。

有更好的主意嗎?

當前代碼:

var def = $.Deferred(),
  data = {
    iTries: 0,
    ....
  };

$.ajax({
  type: "POST",
  url: "POST",
  data: data,
  timeout: 15000,
  success: d => def.resolve(d);,
  error: function(vSocket, status, error) {
    def.notify('error'); // this I want to replace
    data.iTries++;

    //try again
    if (data.iTries < 40) window.setTimeout(function() {
      DoAgain(data, def).then(q => def.resolve(q));
    }, 9000);
    else {
      def.reject();
    }
  }
  else {
    if (data.iTries < 20) window.setTimeout(function() {
      Poll.AjaxPoll(data, def).then(q => def.resolve(q));
    }, 30000);
  }
}
});

從您的代碼看來,您正在使用ES6(您正在使用箭頭功能)。 您可以使用es6箭頭函數和promise遵循遞歸方法,可能是這樣的:

doAjaxRequest(data) {
    fireAPICall(data).then(response => { // fireAPICall is a method that fires the post request and returns the response received from server
        if(response.status == 200) { // success (this if statement is optional)
            // handle success
            let d = response.data;
        }
    }).catch(error => { // failure
        data.iTries++;
        if(data.iTries < 40) {
            window.setTimeout(() => {doAjaxRequest(data)}, 9000); // try again
        } else if(data.iTries < 20) {
            window.setTimeout(() => {doAjaxRequest(data)}, 30000); // try again
        }
    });
}

對於fireAPICall方法,您可以使用任何基於承諾的http客戶端,例如axiosFetch API ,這里我使用axios

fireAPICall(data) {
    return axios.post("url", data);
}

更新 :如果要同時處理reject/failure事件和notify/progress事件,則需要一些服務器端協作。 如果發生進度事件(尚未准備好),您可以使服務器返回202狀態代碼(或其他任何更合適的狀態代碼),並且可以在.then()回調中處理該問題:

doAjaxRequest(data) {
    fireAPICall(data).then(response => { // fireAPICall is a method that fires the post request and returns the response received from server
        if(response.status === 202) { // notify/progress event
            data.iTries++;
            if(data.iTries < 40) {
                window.setTimeout(() => {doAjaxRequest(data)}, 9000); // try again
            } else if(data.iTries < 20) {
                window.setTimeout(() => {doAjaxRequest(data)}, 30000); // try again
            } else {
                return Promise.reject('poll eneded with no success'); // exceeded maximum number of times for polling, so reject. This will invoke the catch callback method with this error
            }
        } else { // handle success
            let d = response.data;
        }
    }).catch(error => { // reject/failure for some other reason
        // handle error
    });
}

如您所說,一個承諾只能被履行一次 (這也適用於jQuery的$.Deferred ,它[現在]大多像承諾一樣。)

定期通知不是諾言的用例。 相反,您需要某種類型的事件發射器或發布/訂閱系統(對於jQuery,也有非常小的系統,例如這種 [不是背書]),或者甚至只是使用進度更新調用的回調。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM