promise, async/await
Promise是抽象異步處理對象以及對其進行各種操作的組件。
1. 基礎
let promise = new Promise(function(resolve, reject) {
// 異步處理
// 處理結束後、調用resolve 或 reject
});
promise.then(resolveFunc).catch(rejectFunc)
// 鏈式寫法
promise.then(resolveFunc1).then(resolveFunc2).catch(rejectFunc)
// promise.catch 等價於 promise.then(null, rejectFunc)
Promise對象有以下三個狀態
- has-resolution: resolve
- has-rejection: reject
- unresolve: 剛創建後的初始化狀態
一旦狀態從unresolve轉變成 resolve或者reject後,就不會再發生人話變化,即在 .then 後執行的函數可以肯定地說只會被調用一次。
var promise = new Promise(function (resolve){
console.log("inner promise"); // $1
resolve("resolve");
});
console.log("outer promise 1"); // $2
promise.then(function(value){
console.log(value); // $4
});
console.log("outer promise 2"); // $3
> inner promise
> outer promise1
> outer promise2
> resolve
執行順序:
- 初始化Promise對象,
$1
被執行 - 緊接着
$2
被執行 - 雖然在調用promise.then時,promise對象已經是確定的狀態,但仍會以異步的形式調用。所以先執行
$3
- 異步執行回調函數,
$4
2. Promise Chain執行順序
2.1 基本執行順序
let promise = Promise.resolve();
// Promise.resolve() 等價於
// new Promise(function(resolve){
// resolve();
// });
promise.then(taskA).then(taskB).catch(onReject).then(finalTask)
note: onReject和final Task的失敗不會觸發reject.
2.2 傳遞參數
function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value); // => 4: (1 + 1) * 2
}
let promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain中出現異常的時候會被調用
console.error(error);
});
- then, catch之前的傳遞的參數可以爲任意對象
- then函數返回的是一個包裝後的Promise對象
標記法
- 點標記法
dot notation
要求對象的屬性必須是有效的標識符(在ECMAScript 3中則不能使用保留字) - 中括號標記法
bracket notation
的話,則可以將非合法標識符作爲對象的屬性名使用
2.3 Promise.all
Promise.all
接收一個 Promise對象的數組作爲參數,當這個數組裏的所有_Promise對象
全部變爲resolve或reject狀態的時候,它纔會去調用 .then
方法。
3. async 和 wait
async 函數的工作方式
- async 函數總是返回一個 Promise 對象
p
。Promise 對象在 async 函數開始執行時被創建。- 函數體執行過程中,可以通過
return
或throw
終止執行。或者通過await
暫停執行,在這種情況下,通常會在以後繼續執行。- 返回 Promise 對象
p
// 1. async 函數總是返回 Promises
async function asyncFunc() {
return "test";
}
asyncFunc().then( (param) => {
console.log(param); // "test"
})
// 2. 通過 await 處理 async 計算的結果和錯誤
// 2.1 單個
async function asyncFunc() {
let result = await otherAsyncFunc();
console.log(result);
// 等價版本
return otherAsyncFunc().then( (result) => { console.log(result); });
}
// 2.2 串
async function asyncFunc() {
let result1 = await otherAsyncFunc1();
console.log(result1);
let result2 = await otherAsyncFunc2();
console.log(result2);
// 等價版本
return otherAsyncFunc1().then( (result) => { console.log(result); return otherAsyncFunc2()})
.then((result) => { console.log(result) });
}
// 2.3 並行
async function asyncFunc() {
let [result1, result2] = await Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2()
])
console.log(result1, result2);
// 等價版本
return Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2()
]).then( ([result1, result2]) => { console.log(result1, result2); } )
}
// 2.4 錯誤處理
async function asyncFunc() {
try {
await otherAsyncFunc();
} catch (err) {
console.error(err);
}
// 等價版本
return otherAsyncFunc().catch( (err) => {
console.error(err);
});
}