首頁技術文章正文

Promise的進階版終極方案

更新時間:2018-11-16 來源:黑馬程序員技術社區(qū) 瀏覽量:

現(xiàn)在大家所用的瀏覽器可謂除了常見的還有不常見的,總體來說是很多,但是
隨著現(xiàn)代瀏覽器的不斷發(fā)展,相信大家漸漸對ES6中的Promise已經(jīng)有很多的使用了,其中對Promise.all估計也用的很多。Promise.all就是并行執(zhí)行多個任務,然后在所有任務成功后觸發(fā)then里面的內(nèi)容,或者任意一個任務失敗后觸發(fā)catch里面的內(nèi)容。

雖然Promise.all非常好用,但它也不是適合所有的場景,最常見的就是有些場景是需要串行的,一個任務列表要按順序依次循環(huán)執(zhí)行,任意一個失敗就不觸發(fā)下面的任務。那要實現(xiàn)這樣的功能能怎么寫呢?

最簡單的就是一個個寫

var a = ()=>{return new Promise((resolve, reject) => {    setTimeout(resolve, 1000);});}var b = ()=>{return new Promise((resolve, reject) => {    setTimeout(resolve, 1000);});}var c = ()=>{return new Promise((resolve, reject) => {    setTimeout(resolve, 1000);});}a().then(()=>{    return b()}).then(()=>{    return c()}).then(()=>{    console.log('after 3 sec')})

這樣寫。。。真的好挫,更重要的是,有時候需要批量處理一個任務,都是調(diào)用同一個函數(shù)處理不定長度的數(shù)據(jù),這樣寫肯定就不行了,比如要串行請求一串url。首先想到的是一個比較繞的方法,搞個Promise鏈出來,把下一個任務作為參數(shù)傳到前一個的then中,如此循環(huán)。這種同一個函數(shù)不斷循環(huán)然后把前一個處理完的值又傳到參數(shù)里面,剛好和Array.reduce的思想是一致的,所以可以這么寫:

var urlArr = ['http://www.qq.com','http://www.qq.com','http://www.qq.com'];function makaPromiseList(dataArr,handler) {    return dataArr.reduce((promise, obj) => {        return promise.then((ret) => {            return handler(obj);        })    }, Promise.resolve())}var result = [];function makeRequest(url){    return new Promise((resolve,reject)=>{        $.get(url).success((ret)=>{            result.push(ret)            resolve(result)        }).fail(()=>{            reject()        })    })}makaPromiseList(urlArr,makeRequest).then((result)=>{    console.log(result)});

老師不給力啊,理解起來就很繞,還要在閉包外面定義result存數(shù)據(jù),用上reduce也覺得有點奇技淫巧,不太美觀啊,能不能寫得更好看點啊。 
可以!說起異步方案,Promise是很強,但它還不是最強的,還有Promise的進階版 —— async/await!號稱JS異步的終極解決方案,真不是蓋的,下面就來看看async/await的方案

var urlArr = ['http://www.qq.com','http://www.qq.com','http://www.qq.com'];function makeRequest(url){    return new Promise((resolve,reject)=>{        $.get(url).success((ret)=>{            resolve(ret)        }).fail(()=>{            reject()        })    })}async function makaPromiseList(dataArr,handler){    var result = [];    for(let item of dataArr){        var ret = await handler(item);        result.push(ret);    }    return result;}makaPromiseList(urlArr,makeRequest).then((ret)=>{    console.log(ret)});

一個for循環(huán)解決串行異步問題,沒有回調(diào)沒有嵌套看起來瞬間舒服多了~

作者:黑馬程序員大數(shù)據(jù)培訓學院
首發(fā):http://web.itheima.com/

分享到:
在線咨詢 我要報名
和我們在線交談!