After the for loop is used in Promise, the final result cannot be obtained. How to modify it if it is changed to promise.all?

the following code, I used to read the database many times, and the data I got was looped, and after the loop, the database was queried. Finally, after resolve, the result I got was only a small part of the data, and the rest of the data was not resolve, but all the data could be printed out through console.log. When resolv was executed, the for loop was not finished.

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; iPP) {
                  var product = res.rows.item(i);
                  categoryIds.push(product.categoryIds)
                  for (var k = 0; k < categoryIds.length; kPP) {
                    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; iPP) {
                            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);
              }
            })
        })
      })
    }
  })
}

I saw the method of using Promise.all () on the Internet before. I modified it to the following code. The code looks fine, but there is no resolve as soon as we get to Promise.all:

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; iPP) {
promise.push(new Promise((resolve,reject)=>{
                  var product = res.rows.item(i);
                  categoryIds.push(product.categoryIds)
                  for (var k = 0; k < categoryIds.length; kPP) {
                    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; iPP) {
                            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);
              }
            })
        })
      })
    }
  })
}

according to the above code, we can"t get the desired results, and the second method is always in the state of pendding. I really don"t know how to solve it. I hope you can give us some advice.


    The query of
  1. db is asynchronous. The resolve of promise should be used in the asynchronous callback function.
  2. your second example has been pending because you didn't use resolve, when querying db in that loop. No resolve or reject or exception, promise has been waiting.

so, every db query should be wrapped in a promise, and then use promise.all. outside In the second example, you are obviously missing a promise.All:
. You also need to create an promise array, and after the loop ends, execute promise.all (promise array), then returns the result using the outermost resolve.

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

after the transformation, the code looks like this (not implemented, just a demonstration):

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; iPP) {
                                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; kPP) {
                                      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; iPP) {
                                                    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);
                        }
                    })
                })
            })
        }
    })
}
Menu