promise, async/await

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對象有以下三個狀態

  1. has-resolution: resolve
  2. has-rejection: reject
  3. 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

執行順序:

  1. 初始化Promise對象,$1 被執行
  2. 緊接着$2被執行
  3. 雖然在調用promise.then時,promise對象已經是確定的狀態,但仍會以異步的形式調用。所以先執行$3
  4. 異步執行回調函數, $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)
Created with Raphaël 2.1.2startTask ATask BFinal TaskonRejectyesnoyesno

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);
    });
  1. then, catch之前的傳遞的參數可以爲任意對象
  2. 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 函數開始執行時被創建。
  • 函數體執行過程中,可以通過 returnthrow 終止執行。或者通過 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);
    });
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章