Promise的基礎我就不說了,我更加關心的是Promise能帶給我什麼便利?這也是本文的內容所在。 Promise.all 併發執行多個非同步方法,統一返回結果,結果按照參數的順序返回。 上面的這個方法能夠很好的看出Promise.all的執行方式,Promise.all的作用是顯而易見的,比如我的 ...
Promise的基礎我就不說了,我更加關心的是Promise能帶給我什麼便利?這也是本文的內容所在。
Promise.all
併發執行多個非同步方法,統一返回結果,結果按照參數的順序返回。
const getRandom = () => +(Math.random()*1000).toFixed(0); const asyncTask = taskID => new Promise(resolve => { let timeout = getRandom(); console.log(`taskID=${taskID} start.`); setTimeout(function() { console.log(`taskID=${taskID} finished in time=${timeout}.`); resolve(taskID) }, timeout); }); Promise.all([asyncTask(1),asyncTask(2),asyncTask(3)]) .then(resultList => { console.log('results:',resultList); });
上面的這個方法能夠很好的看出Promise.all的執行方式,Promise.all的作用是顯而易見的,比如我的頁面上有多個請求,但是這些請求並沒有任何聯繫,但是整個頁面需要等這幾個請求數據都獲取到之後我們才能正確的展示頁面,在之前一段時間里,我們可能會使用嵌套的方式去逐個請求,但考慮到這樣會浪費時間,我們可能會優化自己的寫法,通過計時器的方式去處理。其實計時器的原理跟Promise.all的實現的結果就差不多,而有了Promise.all之後就可以直接把幾個非同步的請求方法作為參數直接調用Promise.all了,so easy不是嗎?
Promise.race
併發執行多個非同步方法,返回最快的執行結果。
const getRandom = () => +(Math.random()*1000).toFixed(0); const asyncTask = taskID => new Promise(resolve => { let timeout = getRandom(); console.log(`taskID=${taskID} start.`); setTimeout(function() { console.log(`taskID=${taskID} finished in time=${timeout}.`); resolve(taskID) }, timeout); }); Promise.race([asyncTask(1),asyncTask(2),asyncTask(3)]) .then(resultList => { console.log('results:',resultList); });
同樣的這個例子也能很好的說明race的作用,race的作用,為了保障能夠獲取到數據,我們通過多個不同的方法去獲取數據,但其實這幾個方法返回的數據是相同的,只要任何一個方法成功返回了,我們就可以獲取到自己想要的數據了。
看了上面兩個例子之後是不是對Promise的作用更加瞭解了,其實前端業務開發中只要有了多個非同步方法就可以使用Promise了,這也是目前最優雅的編碼方式。儘量去用就對了,沒毛病。
上面兩種方法是Promise自帶的,但是實際情況中有很多情況下,多個請求之間是有依賴關係的,所以我新增waterfall方法
Promise.waterfall
多個函數依次執行,且前一個的輸出為後一個的輸入。
實現如下麵:
Promise.waterfall = function(promises){ if (!Array.isArray(promises)) { throw new TypeError('You must pass an array to all.'); } // 返回一個promise 實例 return new Promise(function(resolve, reject){ var i = 0, result = [], len = promises.length, count = len; // 每一個 promise 執行成功後,就會調用一次 resolve 函數 function resolver(index) { return function(value) { resolveWaterfall(index, value); }; } function rejecter(reason){ reject(reason); } function resolveWaterfall(index, value) { if( index == len){ resolve(value) } else { promises[index](value).then(resolver(index + 1), rejecter); } } resolveWaterfall(0); }); };
同樣的我們通過一段測試代碼來看其執行結果
const getRandom = () => +(Math.random()*1000).toFixed(0); const asyncTask = taskID => new Promise(resolve => { taskID = taskID || 1; let timeout = getRandom(); console.log(`taskID=${taskID} start.`); setTimeout(function() { console.log(`taskID=${taskID} finished in time=${timeout}.`); resolve(taskID + 1) }, timeout); }); Promise.waterfall([asyncTask, asyncTask, asyncTask]).then(value => console.log(value))
返回的結果是4,三個非同步方法依次執行,並且把前一次的輸出作為下一次的輸入執行。