2016年7月25日 星期一

ECMAScript 6: Promise, Collections


Promise

一個基礎的 Promise 宣告:
let status = false;
let p = new Promise(function(resolve,reject){
 
    //do something
 
    if(status){
        resolve("OK");  //丟出正確
    }else{
        reject("Dead"); //丟出回絕
    }

});

//實作
p.then(function(resolve){
    //正確的話會進入
    console.log(resolve); // "OK"
}).catch(function(reject){ //選擇性再加一個 .catch 選擇是否要接收 reject (回絕參數) 值
    //如果被回絕才會進入
    console.log(reject); //"Dead" 
});


Promise.resolve

Promise.resolve 和 Promise.reject 都可以直接把現有物件轉換成 Promise, 一般來說, resolve 會直接接收成接受的 Promise:
Promise.resolve('Hello').then(function (resolve){
    console.log(resolve)
});

Promise.reject

Promise.reject 會直接轉換物件為 reject:
var p = Promise.reject('Dead');

p.then(new Error('fail'), function (reason){
  console.log(reason)
});

Promise.all

Promise.all 會把所有 Promise 執行後,分別會丟出正確和失敗的值。
只寫一個 function 當接收 callback 的情況下,會接收所有 resolve 的值,但 reject 會出錯,所以要自行在 .then 結束後加上 .catch(function(e){}) 來接收錯誤。

有兩個 function 當作 callback 的情況下,只有全部成功才會進入第一個 callback function,如果有一個出錯,會在第二個 callback function 顯示錯誤的那個 reject 參數。

var a = Promise.resolve(10);
var b = Promise.resolve(20);
var c = Promise.resolve(30);
var d = Promise.resolve(40);
var e = Promise.reject(50); //出錯

Promise.all([a,b,c,d,e]).then(function(resolve){ //接收 resolve 的值
    console.log(resolve); //10 20 30 40, 但是 e 出錯,這裡就不會顯示任何東西
},function(reject){ //接收 reject 的值
    console.log(reject); //50   e 出錯
});

Promise.race (競賽模式)

Promise.race 一樣會執行所有 Promise, 只要碰到一個正確或失敗,就會跳出 callback。(有時間影響的話,也會從最先回傳的那個人回傳)

這裡分別用 3 種方式進行測試, a 會馬上回傳 resolve, b 等待 10 毫秒才會回傳 resolve, c 馬上跳錯。

以下 race 只有一個 function 的參數下,只接收 resolve 的值,要自行加上 .catch 在 then 後面,如果有兩個 function 當作 callback 的參數下,會判斷第一個接收者是 resolve (丟到第一個 function 參數),如果是 reject,就會丟到第二個 function 參數。

var a = Promise.resolve(10);
var b = new Promise(function(resolve){
 setTimeout(function(){
  resolve(20);
 },10);
});
var c = Promise.reject("Dead");

//注意 [] 中的順序, b 雖然第一個開始跑,但是要延遲,所以 a 因為馬上就執行,就先回傳。
Promise.race([b,a,c]).then(function(resolve){ //接收 resolve 的值
    console.log(resolve); //10 20 30 40
},function(e){
 console.log(e);
});
---

Collections

Collections 集合模式的幾種重要類別如下:

Map

Map 和一般 Array/Object 比較,最大的差距就是 key 鍵值,Map 鍵值可以丟入 object ,但是 Object 鍵值只能丟 String。
let a = {}
//a[{id:1}] //error

//Map:

a = new Map();
//a["X"] //error 不能當作 object 使用。

let key = {id:1}; //注意, 一定要丟這個 key, 如果產生一個 object, map 會偵測 object id ,所以新建立的 object 會讀不到 map 的值

// a.set({id:1}, "Me"); //這樣 get 絕對得不到東西。
a.set(key, "Me");
a.get(key); // Me

//迭代方式:
for(let i of a){
    console.log(i);
}

Set

Set 特性是沒有 key/value 樣式,且不允許重複的值,重複設定的值會被忽略。
var set = new Set();

set.add(1);
set.add(1); //忽略
set.add(2);
set.add("Hello world");

for(let i of set){
    console.log(i);
}

WeakMap

WeakMap 和 Map 用法一樣,只是 Map 中的 key 只要任一個被指定 null, 而且沒有指向任何參考,就會自動被回收 (消失)。

WeakSet

WeakSet 是只要任一值被指定 null, 就會自動被回收 (消失)。

Reference;
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject
https://wohugb.gitbooks.io/ecmascript-6/content/docs/promise.html
https://medium.com/@WendellLiu/%E5%88%A5%E9%80%99%E6%A8%A3%E4%BD%BF%E7%94%A8promise-d4f5a731adb4
https://juejin.im/entry/5844c8e2128fe100577d15e4

沒有留言:

張貼留言

© Mac Taylor, 歡迎自由轉貼。
Background Email Pattern by Toby Elliott
Since 2014