EZTABLE IDEAS 是 EZTABLE 成員揮灑熱情和大家分享專業及創意的網誌。 EZTABLE 讓消費者 24 小時都可以在網路訂位全台灣最優質的餐廳,同時提供餐廳經營者 e 化的訂位管理系統 (雲端、iPad、智慧型手機)

JavaScript Promise 介紹

十二月 17 2013 Published by under Engineering

 

Promise 抽象化表達一個概念,就是一個動作有兩種可能,一個是丟給你結果,一個是發生錯誤。抽象成這樣之後,在 Async Code 的 JavaScript 世界中,會變的比較好讀,典型例子:

readFile("file.json", function(err, val) {
    if( err ) {
        console.error("unable to read file");
    }
    else {
        try {
            val = JSON.parse(val);
            console.log(val.success);
        }
        catch( e ) {
            console.error("invalid json in file");
        }
    }
});

如果 readFile 支援 Promise 可以改寫成如下

readFile("file.json").then(JSON.parse).then(function(val) {
    console.log(val.success);
})
.catch(SyntaxError, function(e) {
    console.error("invalid json in file");
})
.catch(function(e){
    console.error("unable to read file")
});

讀起來會像一般try-catch的流程。原本 readFile 的第二個 argument 是傳入一個 Callback ,當檔案讀取好時, Callback 會被執行。改成用 Promise 的方式後, readFile(‘file.json’) 會回傳一個 Promise 的物件,會有 then 的 method 可以使用;Callback 從參數中被分離出來了,它的使用權回到 caller 那一層,這樣可以產生更多彈性。

Propagation

Promise 中 then return 的東西大有玄機,有三種情況

  1. Promise: 下一個 then 會是一個全新的 Promise
  2. Value: 這個 Promise 已經被滿足了,之後串接的 then 都會是此 Value
  3. Throw exception: 這個 Promise 發生問題,之後的 then 都不會執行,會改執行 fail 的 callback

Chaining

就是上述第一點,可以改善 Callback Hell ,讓 nested 的 callback 少一點

return getUsername()
.then(function (username) {
    return getUser(username); // new promise
})
.then(function (user) {

});

Combination

當有多個 Promise ,而你想要等這些 Promise 都執行完(fulfilled),才要執行下一步的話,可以使用這個非常 awesome 的用法

Promise.all([promiseA, promiseB, promiseC]).then(function () {
    console.log "A, B, C has done!"
});

Handling Errors

除了 then 之外,還有 catch 的 method 來接 chaining 過程中有發生的 exception ,用 done() 會讓未處理的 exception 噴出來

Promise Creation

假設我們要把 readFile 包裝成 Promise ,可以這麼做

var deferred = Promise.defer();
FS.readFile("foo.txt", "utf-8", function (error, text) {
    if (error) {
        deferred.reject(new Error(error));
    } else {
        deferred.resolve(text);
    }
});
return deferred.promise;

reslove 的值會 pass 到一個接 then 的, reject 會 pass 到 catch 。 這樣就可以輕鬆建立 Promise ,也可以用 when 來包裝單純 value

Summary

總結來說, Promise 提供了一套抽象化的方法,來處理 Async Code ,讓 Async Code 可以更好管理。今天會想寫這篇是因為看到這篇介紹, Promise 要正式登場,之後就可以原生使用這功能拉,大家快來熟悉一下,這看似困難卻又非常優雅的 Design 。

這邊的範例都是從 Q 截取而來。


Related Posts Plugin for WordPress, Blogger...

No responses yet

發表迴響