鍍金池/ 問答/HTML/ Promise中使用了for循環(huán)后,不能獲取到最終結(jié)果,如果改為promise.

Promise中使用了for循環(huán)后,不能獲取到最終結(jié)果,如果改為promise.all該如何修改

如下代碼,我其中使用了多次讀取數(shù)據(jù)庫,并且獲取到的數(shù)據(jù)在進(jìn)行循環(huán),循環(huán)后在進(jìn)行數(shù)據(jù)庫查詢,最終resolve后,我得到的結(jié)果僅僅只是一小部分?jǐn)?shù)據(jù),還剩余一部分?jǐn)?shù)據(jù)并未resolve,但是通過console.log可以打印出所有數(shù)據(jù),resolv執(zhí)行的時候,其實for循環(huán)還未執(zhí)行完

getProducts(params) {
  return new Promise((resolve, reject) => {
    if (params) {
      this.getDb().then((db: SQLiteObject) => {
        db.transaction((run) => {
          var sql = 'SELECT * FROM product_content';
          run.executeSql(sql, [],
            (run, res) => {
              if (res.rows.length != 0) {
                let result = {
                   product_ids: {}
                };
                let retTmp = []
                let exTmp = [1,2,100,600,500,800,900,700,701,300]
                let categoryIds = []
                for (var i = 0; i < res.rows.length; i++) {
                  var product = res.rows.item(i);
                  categoryIds.push(product.categoryIds)
                  for (var k = 0; k < categoryIds.length; k++) {
                    var _cid = categoryIds[k]
                    sql = 'select id FROM product where category like "%,' + _cid + ',%"';
                    run.executeSql(sql, [],
                      (run, res_id) => {
                        if (res_id.rows.length != 0) {
                          for (var i = 0; i < res_id.rows.length; i++) {
                            var productId = res_id.rows.item(i).ID
                            retTmp.push(productId)
                          }
                        }
                      })
                  }
                }
                // setTimeout(() => {
                  let newRetTmp = Array.from(new Set(retTmp))
                  let newExTmp = Array.from(new Set())

                  if (newExTmp.length > 0) {
                    newRetTmp.map((rettmp, index) => {
                      exTmp.map(extmp => {
                        if (rettmp != extmp) {
                          result.product_ids[newRet] = true
                        }
                      })
                    })
                  }

                  resolve(result);
                // }, 500)
              } else {
                let result = {
                  data: {
                    product_ids: {}
                  }
                };
                resolve(result);
              }
            })
        })
      })
    }
  })
}

之前在網(wǎng)上看到使用Promise.all()的方法,我將其修改成如下代碼,代碼看上去沒有什么問題,但是一到Promise.all的地方就一直沒有resolve了:

getProducts(params) {
  return new Promise((resolve, reject) => {
    if (params) {
      this.getDb().then((db: SQLiteObject) => {
        db.transaction((run) => {
          var sql = 'SELECT * FROM product_content';
          run.executeSql(sql, [],
            (run, res) => {
              if (res.rows.length != 0) {
                let result = {
                    product_ids: {}
                };
                let retTmp = []
                let exTmp = [1,2,100,600,500,800,900,700,701,300]
                let categoryIds = []
                let promise = []
                for (var i = 0; i < res.rows.length; i++) {
promise.push(new Promise((resolve,reject)=>{
                  var product = res.rows.item(i);
                  categoryIds.push(product.categoryIds)
                  for (var k = 0; k < categoryIds.length; k++) {
                    var _cid = categoryIds[k]
                    sql = 'select id FROM product where category like "%,' + _cid + ',%"';
                    run.executeSql(sql, [],
                      (run, res_id) => {
                        if (res_id.rows.length != 0) {
                          for (var i = 0; i < res_id.rows.length; i++) {
                            var productId = res_id.rows.item(i).ID
                            retTmp.push(productId)
                            // this.helperService.console('c0', productId)
                          }
                        }
                      })
                  }
}))
                }
Promise.all(promise).then(res => {
              // setTimeout(() => {
                let ATmp = Array.from(new Set(retTmp))

                if (newExTmp.length > 0) {
                  exTmp.map((rettmp, index) => {
                    newExTmp.map(extmp => {
                      if (rettmp != extmp) {
                        result.product_ids[newRet] = true
                      }
                    })
                  })
                }
                resolve(result);
              // }, 500)
})
                
              } else {
                let result = {
                  data: {
                    product_ids: {}
                  }
                };
                resolve(result);
              }
            })
        })
      })
    }
  })
}

根據(jù)以上代碼,都無法得到想要的結(jié)果,第二種方法更是一直處于pendding狀態(tài),真不知道該如何進(jìn)行解決,望各位大神支招

回答
編輯回答
綰青絲
  1. db的查詢?yōu)楫惒剑琾romise的resolve請在異步的回調(diào)函數(shù)中使用。
  2. 你第二個例子一直pending是因為你沒有在那個循環(huán)查詢db時使用resolve,沒有resolve或reject或異常,promise一直等待。

所以,每一次db查詢都應(yīng)被包裹在一個promise中,然后外面使用promise.all. 第二個例子,明顯你還少用了一個promise.All:
下面這段代碼處,也需要創(chuàng)建一個promise數(shù)組,循環(huán)結(jié)束后,執(zhí)行promise.all(promise數(shù)組),then 將結(jié)果使用最外側(cè)的resolve返回。

sql = 'select id FROM product where category like "%,' + _cid + ',%"';
run.executeSql(sql, [], ...

改造后,大概代碼時這個樣子的(并未執(zhí)行過,只是示范):

getProducts(params) {
    return new Promise((resolve, reject) =>{
        if (params) {
            this.getDb().then((db: SQLiteObject) =>{
                db.transaction((run) =>{
                    var sql = 'SELECT * FROM product_content';
                    run.executeSql(sql, [], (run, res) =>{
                        if (res.rows.length != 0) {
                            let result = {
                                product_ids: {}
                            };
                            let retTmp = [];
                            let exTmp = [1, 2, 100, 600, 500, 800, 900, 700, 701, 300]; 
                            let categoryIds = [];
                            let promise = [];
                            for (var i = 0; i < res.rows.length; i++) {
                                promise.push(new Promise((resolve1, reject1) =>{
                                    var product = res.rows.item(i);
                                    categoryIds.push(product.categoryIds);
                                    var innerPromise = [];
                                    for (var k = 0; k < categoryIds.length; k++) {
                                      innerPromise.push(new Promise((resolve2, reject2) => {
                                        var _cid = categoryIds[k];

                                        sql = 'select id FROM product where category like "%,' + _cid + ',%"';
                                        run.executeSql(sql, [], (run, res_id) =>{
                                            if (res_id.rows.length != 0) {
                                                var productids = [];
                                                for (var i = 0; i < res_id.rows.length; i++) {
                                                    var productId = res_id.rows.item(i).ID retTmp.push(productId)
                                                    // this.helperService.console('c0', productId)
                                                    productids.push(productId);
                                                }
                                                resolve2(productids);
                                            } else {
                                                resolve2([]);
                                            }
                                        });
                                      }));
                                    }
                                    Promise.all(innerPromise).then(productIdsArray=>resolve1(productIdsArray));
                                }))
                            }
                            Promise.all(promise).then(res =>{
                                // setTimeout(() => {
                                let ATmp = Array.from(new Set(retTmp))

                                if (newExTmp.length > 0) {
                                    exTmp.map((rettmp, index) =>{
                                        newExTmp.map(extmp =>{
                                            if (rettmp != extmp) {
                                                result.product_ids[newRet] = true
                                            }
                                        })
                                    })
                                }
                                resolve(result);
                                // }, 500)
                            })

                        } else {
                            let result = {
                                data: {
                                    product_ids: {}
                                }
                            };
                            resolve(result);
                        }
                    })
                })
            })
        }
    })
}
2017年10月1日 07:04