關於循環promise的解決方案


es6的promise對象解決了js異步回調函數多重嵌套的的噩夢,再也不用寫像這樣的代碼

query('select * from user',function(err,data) {
    query('select * from user1',function(err,data) {
        query('select * from user2',function(err,data) {
            //無窮無盡的異步操作。。。
        })
    })
})

而可以像這樣。

query('select * from user')
.then(function(data) {
    return query('select * from user1')
})
.then(function(data) {
    return query('select * from user2')
})
.then(function(data) {
    //后續操作。。。
})

代碼的可讀性得到了大大的提升,並且更容易維護。但是promise並不是萬能的,比如說在循環中有多個異步操作,有無窮多個then函數就比較麻煩了,比如這樣

//查詢訂單及每個訂單的每個商品
query('select * from order')
.then(data => {
    var orders = data
    for(let order of orders) {
        query('select * from order_prod where oid='+order.oid)
        .then(data => {
            order.prods = data
        })
    }
 //最終需要得到結果
   console.log(orders)
})

 

這里需要得到最終的結果就比較令人頭疼了,好在es7的async/await異步方案為我們提供了解決方案。node.js7.6已經原生支持async/await,所以把node更新到7.6以上,就可以放心使用啦。async 可以聲明一個異步函數,此函數需要返回一個 Promise 對象。await 可以等待一個 Promise 對象 resolve,並拿到結果。比如這樣

async function sleep(timeout) {  
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      resolve();
    }, timeout);
  });
}

(async function() {
  console.log('Do some thing, ' + new Date());
  await sleep(3000);
  console.log('Do other things, ' + new Date());
})();
//Do some thing, Mon Feb 23 2015 21:52:11 GMT+0800 (CST)  
//Do other things, Mon Feb 23 2015 21:52:14 GMT+0800 (CST)

所以在循環promise取得最終結果就可以是這樣 

let getOrderProd = async data => {
    var order = data
    for(let order of orders) {
        //將之前封裝的基於promised的query函數還原成普通的異步回調模式
        await f(order)
    }
    //最終需要得到結果
    console.log(orders)
    return new Promise((reslove,reject) => {
        reslove(orders)
    })
}
function f(i) {
 return new Promise((resolve,reject) => {
  query1('select * from order_prod where oid='+order.oid, function(err,data){
      i.prods = data
      resolve(i)
    })
 })
}

query('select * from order')
.then(getOrderProd).then(data => {
    //后續操作。。。。。
})

 

這樣循環異步操作的問題就解決了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM