[英]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客戶端,例如axios或Fetch 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.