Javascript在Async Loop结束时执行

时间:2018-03-21 09:00:14

标签: javascript loops for-loop asynchronous

我对Javascript中的异步代码感到非常糟糕,现在已经停留了一段时间。

我正在使用WebSql并且只是通过数据库初始化步骤,但其中一个循环没有以我期望的方式执行。

XSD

但是指示结束的日志在for循环结束之前执行。如果我尝试验证数据是否已插入,我总是会失败,因为循环尚未完成插入。

Google表示应该使用promises处理异步代码,但我找不到像这样的实例中使用的promise的示例。

非常感谢任何帮助

2 个答案:

答案 0 :(得分:1)

将每个回调转换为promise,然后使用Promise.all



    const loDataPromises = lo_data.map(({ code, desc }) => {
      return new Promise((resolve, reject) => {
        trans.executeSql(
          "INSERT",
          [code, desc],
          function(trans, result) {
            console.log('success');
            resolve();
          },
          function(error) {
            console.log('failed');
            reject();
          }
        );
      });
    });

    Promise.all(loDataPromises)
      .then(() => {
        console.log('all done');
      });




答案 1 :(得分:0)

我还没能在互联网上找到任何明确的代码示例,所以我想在这里发布工作版本作为答案。希望它也有益于某人也试图理解承诺和承诺循环。

经过彻底检修后,我设法让它以一种有意义的方式运作。我已将其更改为作为承诺链执行,然后带有for循环的函数正在使用promise all逻辑。

$(document).ready(function() {

   ////
   // promise chain
   ////

   console.log("BEGIN");
   f_initdatabase().then(function(result) {
      return f_defaultdata(result.db);
   }).then(function(result) {
      console.log("END");
   }).catch(function(result) {
      // abandon all hope
   });

});

////
// single promise usage
////

function f_initdatabase() {
return new Promise(function(resolve, reject) {

   console.log("   INIT DB");

   var lo_result = {db:null};

   var lv_db = window.openDatabase("thenothing", "1.0", "The Nothing DB", 2 * 1024 * 1024);

   lv_db.transaction(function(trans) {

      trans.executeSql ("create table if not exists dummydata (dd_idno integer primary key, dd_code text not null, dd_desc text not null)", [], function(trans, results) {
         console.log("   INIT DB : DONE");
         lo_result.db = lv_db;
         resolve(lo_result);
      }, function(error) {
         lo_result.db = null;
         reject(lo_result);
      });

   });

});
}

////
// loop promise all usage
////

function f_defaultdata(lv_db) {
return new Promise(function(resolve, reject) {

   console.log("   DEF DATA");

   var lo_result = {db:null};

   lv_db.transaction(function(trans) {

      var la_promises = [];

      var lo_data = [
         {dd_code:"CODE01", dd_desc:"Code 01 Desc"},
         {dd_code:"CODE02", dd_desc:"Code 02 Desc"},
         {dd_code:"CODE03", dd_desc:"Code 03 Desc"}
      ];

      for(i = 0; i < lo_data.length; i++) {

         console.log("      INS : " + i);
         trans.executeSql (" insert into dummydata (dd_code, dd_desc) values (?, ?)", [lo_data[i].dd_code, lo_data[i].dd_desc], function(trans, results) {
            la_promises.push(resolve(lo_result));
         }, function(error) {
            la_promises.push(reject(lo_result));
         });

      }

      Promise.all(la_promises).then(function(results) {
         console.log("   DEF DATA : DONE");
         lo_result.db = lv_db;
         resolve(lo_result);
      }).catch(function() {
         lo_result.db = null;
         reject(lo_result);
      });

   });

});
}

根据所需的流程提供输出

BEGIN
   INIT DB
   INIT DB : DONE
   DEF DATA
      INS : 0
      INS : 1
      INS : 2
   DEF DATA : DONE
END