Nodejs與ES6系列2:Promise物件

帥蟲哥發表於2016-06-19

2、promise物件

js單執行緒非同步執行的特性,因此在程式碼中充斥著回撥函式。隨著回撥函式的增加,程式碼的可讀性會愈來愈差,因此引入promise物件是不錯的一種選擇,可以避免層層回撥函式。在ECMA6中提供了原生的promise物件而不再需要第三庫。

2.1 promise構造

ECMA6中所提供的promise物件是由建構函式生成的,基本用法如下:

程式碼 2.1.1

new Promise(function (resolver, reject) {
    if (success)
        resolver(data)
    else
        reject(error)
});

在promise的建構函式中接受(一個帶有兩個引數的)函式做為入參,兩個引數分別是resolver和reject,用於在非同步回撥中將狀態改為成功,或將狀態改為失敗。程式碼2.1.2展示promise的簡單示例:

var getData = function (data) {
    return new Promise(function (resolver, reject) {
        if (data === -1)
            reject(data);
        setTimeout(resolver([1, 2, 3, 4, 5]), 1);
    })
}

getdata是一個返回promise物件的函式,通過setTimeout來模擬非同步操作,當操作成功返回陣列[],當輸入引數為-1時返回失敗狀態。程式碼2.1.3呼叫getdata函式並返回結果,通過then方法得到成功後回撥,而通過catch指定失敗後的回撥,除了通過catch方法指定失敗回撥外,還可以通過then方法的第二引數指定失敗回撥,兩種方式等價。

getData(1).then(function (data) {
    console.log(data);
}).catch(function (data) {
    console.log('出現異常:'+data);
})
====
[ -1, 2, 3, 4, 5 ]

2.2、promise.all

很多業務場景需要對資料進行集合操作,例如傳送資料取出一個集合資料,遍歷集合資料將集合資料又傳送至另一個介面取資料,這是一個典型的二次呼叫介面方法,此時就需要使用到promise.all 方法。

// return 集合
var getData = function (data) {
    return new Promise(function (resolver, reject) {
        if (data === -1)
            reject(data);
        setTimeout(resolver([-1, 2, 3, 4, 5]), 1);
    })
}


var getdataInfo = function (data) {
    return new Promise(function (resolver, reject) {
        if (data === -1)
            reject(data);
        console.log(data + '的詳情是...');
        setTimeout(resolver(data), 1);
    })
}

getData(1).then(function (data) {
    var array = data.map(getdataInfo);
    Promise.all(array).then(function (data) {
        console.log('全部請求成功');
    }).catch(function (data) {
        console.log('資料' + data + '失敗');
    });
})

getdata函式返回一個集合,集合中的資料作為getdatainfo的函式的引數,而datainfo函式也是一個非同步操作,首先通過陣列map方法生成promise物件的陣列,然後呼叫promise.all(array)呼叫promise陣列,當整個promise都返回時觸發promise.all的then方法,當其中一個失敗的時候觸發catch方法。

相關文章