Promise的基礎我就不說了,我更加關心的是Promise能帶給我什麼便利?這也是本文的內容所在。javascript
併發執行多個異步方法,統一返回結果,結果按照參數的順序返回。前端
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不是嗎?java
併發執行多個異步方法,返回最快的執行結果。promise
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了,這也是目前最優雅的編碼方式。儘可能去用就對了,沒毛病。dom
上面兩種方法是Promise自帶的,可是實際狀況中有不少狀況下,多個請求之間是有依賴關係的,因此我新增waterfall方法異步
多個函數依次執行,且前一個的輸出爲後一個的輸入。async
實現以下面:函數
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,三個異步方法依次執行,而且把前一次的輸出做爲下一次的輸入執行。