ES6 -- 從callback到Generator、Promise, 再到ES7的Async -- Part 1/5

Generator、Promise是我在學習JavaScript ES6中最花心力學習的部分...

如果要理解Generator和Promise, 那麼理解的順序應為: callback --> Promise --> Generator --> Async (ES7)


首先這篇會先介紹Promise:

使用Promise的好處:

1. 當我們希望將非同步操作統一成相同的介面接口

2. 用在將多個非同步操作完成後, 再執行某特定的程式 --> 如我們想確認所有的callbacks皆有執行完了嗎?


在ES5要做到上面第2點需要這麼寫:

e.g.

function asyncTask1(success, time, callback) {

    setTimeout(function() {

        if (success) {                                                        // 在此確認是否success

            callback(true, time);

        } else {

            callback(false, time);

        }

    }, time);

}

function fetchAll(tasks, success, error) {

    var results = Array(tasks.length);                        // 先建立一個空陣列, 用來放callbacks
    var count = 0;                                                         // 建立一個計數器, 當數字和放callbacks的陣列長度相同時, 代表所有callbacks已完成

    for (var i = 0; i < tasks.length; i++) {                   // 每個callback跑完就跑一個loop, 用這種方式去檢查全部的callbacks是否完成

        (function(i) {

            asyncTask1(tasks[i].success, tasks[i].time, function(resolve, data) {

                if (resolve) {

                    count++;
                    results[i] = data;

                    if (count === tasks.length) {               // 當兩者數字相同, 就能確認所有callbacks已完成

                        success(results);

                    }
                } else {

                    error(data);

                }

            });

        })(i);

    }

}

fetchAll([

    {success:true, time:1000},                                    // 1st callback --> 1 sec後回呼
    {success:true, time:5000},                                    // 2nd callback --> 5 sec後回呼
    {success:true, time:2500},                                    // 3rd callback --> 2.5 sec後回呼

],function(data) {

    console.log("ok:", data);                                     // ok: [1000, 5000, 2500]

},function(err) {

    console.log("err:", err);

});



在ES6中可用Promise:

e.g.

function asyncTask2(success, time) {

    return new Promise((resolve, reject) => {          

        setTimeout(() => {

            if (success) {

                resolve(time);                                                // 成功就呼叫resolve()

            } else {

                reject(time);                                                  // 失敗就呼叫reject()

            }

        }, time);

    });

}

Promise.all([                                                                   // 當所有callback完成會回傳一個promise物件。但萬一任何一個callbacks失敗就會回傳第一個失敗的promise物件(並會說明失敗原因)

    asyncTask2(true, 1000),                                          // 1st callback --> 1 sec後回呼
    asyncTask2(true, 5000),                                          // 2nd callback --> 5 sec後回呼
    asyncTask2(true, 2500)                                           // 3rd callback --> 2.5 sec後回呼

]).then(data => {

    console.log("ok:", data);                                        // ok: [1000, 5000, 2500]

}, err => {

    console.log("err:", err);

});



最後, 介紹一下Promise:

1. Promise用來處理非同步的操作。Promise物件代表一個目前還不能用(not available), 但在未來某個時間點可被解析的值。

2. resolve和reject函式會當成傳入new Promise(function(resolve, reject){});中的引數(arguments),用來分別表示resolve或reject一個promise。如果成功會回傳成功的值; 如果失敗會回傳失敗的原因。

3. Promise有3個狀態(states):

    i. pending: initial state, 不是fulfilled, 也不是rejected state
    ii. fulfilled: 意思是operation completed successfully
    iii. rejected: 意思是operation failed

4.Promise的方法們:

   a. Promise.all(): 當所有callback完成會回傳一個promise物件。但萬一任何一個callbacks失敗就會回傳第一個失敗的promise物件(並會說明失敗原因)。

   b. Promise.reject(reason): 如果操作失敗, 就回傳一個含失敗原因的Promise物件。

   c. Promise.resolve(value): 如果操作成功, 就回傳一個已resolved的值。如果有加then(), 則會回傳經then()處理過後的值。

   d. Promise.catch(onRejected): 當操作失敗, 要做些什麼事時, 用這個方法。

   e. Promise.then(onFulfilled, onRejected): 當操作成功時, 要做什麼事; 當操作失敗時, 要做什麼事。



恩... 上面介紹看完還是滿抽象的, 那看以下這篇文章(英文連結是原文, 中文連結是翻譯), 裡面有個實用的例子, 是用Promise處裡Ajax:


英文連結: An Overview of JavaScript Promises

https://www.sitepoint.com/overview-javascript-promises/

中文連結: 理解什麼是JavaScript Promises  (覺得有些翻的不好, 如Error對象應為Error物件(object), 可以中英交互參考著看)

http://www.html-js.com/article/Learn-JavaScript-every-day-to-understand-what-JavaScript-Promises



留言

熱門文章