理解promise,實現非同步的同步編寫
MND解釋:Promise 對象用於表示一個非同步操作的最終狀態(完成或失敗),以及其返回的值。
我的理解就是promise是一種完成非同步功能並檢查狀態觸發回調的機制。
1、兩種常用創建方式:
聲明一個變數:(聲明一個promise類型的對象)
const myFirstPromise = new Promise((resolve, reject) => {
// ?做一些非同步操作,最終會調用下面兩者之一:
//
resolve(result); // fulfilled
// ?或
reject(error); // rejected
});
聲明一個函數:(返回一個promise類型的對象)
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
};
顯而易見,如果需要給非同步過程傳遞函數,當然要優先選擇第2種方式了。
2、promise的狀態
promise的中文釋義為承諾,對象如其名,在未來的某一個時刻將會有狀態變化進而有真實的結果。當代碼執行到變數myFirstPromise或調用函數myAsyncFunction時,得到的都應該是一個空值或空對象,同時會有一個new promise()對象被構建。此時的promise對象處於一種名為pending狀態,表示為初始狀態。此時promise開始執行。
new promise( /*...code...*/ ) 中的code只是相當於一個參數被傳遞給promise對象,和以往的函數調用傳參的不同在於:code是函數類型的參數 (resolve, reject) => { } ,不是一個字元串、數值等等類型的參數。這個函數類型的參數code只接收resolve、reject兩種類型的參數。code函數體內可以正常使用當前文件里的變數參數、函數等等。
promise執行過程中,對我們來說最終的就是這個具有定製意義的code參數,該參數可以是一個XHR請求、setTimeout()函數等等。執行code,如果順利完成,得到我們預期的正確結果,promise對象將處於一種名為fulfilled狀態,表示操作成功完成。執行code,如果未完成,將可以報錯,promise對象將處於一種名為rejected狀態,表示操作失敗。此時我們之前聲明的變數或函數的調用將有一個結果:兌現承諾,得到的仍然是之前的promise,只是此時此刻,它有了新的狀態,表明之前的承諾有了結果。
3、promise的回調
promise狀態從pending改變後,它將觸發(非同步調用)相應的函數(如同我們之前常用的回調函數),這些函數存在於promise的yuanxing里如then()、catch(),當然還有一個finally()。
myFirstPromise.then( // 記錄填充值
function(val) {
console.log("兌現成功的promise", val);
})
.catch( // 記錄失敗原因
(reason) => {
console.log("處理失敗的 promise", reason);
});
finally回調函數:
4、promise的來源
在JavaScript的世界中,所有代碼都是單線程執行的。但如網路操作,瀏覽器事件,都必須是非同步執行。對於需要非同步執行的代碼,js不會立即去執行,而是把它扔到一個事件隊列裡面,當所有同步任務都幹完了以後,再去遍歷執行事件隊列裡面的代碼。一個已經變成 resolve 狀態的 promise,傳遞給 then 的函數也總是會被非同步調用。
promise替代了下面這種舊式的函數,
function successCallback(result) {
console.log("It succeeded with " + result);
}
function failureCallback(error) {
console.log("It failed with " + error);
}
doSomething(successCallback, failureCallback);
提供了新式的函數:
const promise = doSomething();
promise.then(successCallback, failureCallback);
//或者
doSomething().then(successCallback).catch(failureCallback);
TAG:程序員小新人學習 |