Cordova SQLite等待插入完成



在启动SELECT请求之前,我有多个INSERT需要完成。我的问题是,当SELECT触发时,INSERT还没有完成。

建立数据库处理工厂:
databaseFactory.js

factory.insertIntoTable= function (database, data) {
  var sqlCommand = 'INSERT INTO blablabla';
  database.transaction(function(tx) {
    database.executeSql(sqlCommand, [data.thingsToInsert], function (resultSet) {
      console.log('success: insertIntoTable');
    }, function (error) {
      console.log('SELECT error: ' + error.message);
    });
  }, function(error) {
    console.log('transaction error: ' + error.message);
    database.close();
  }, function() {
    console.log('transaction ok: insertIntoTable');
  });
};

app.js

ionic.Platform.ready(function () {
  if (window.cordova && window.cordova.plugins.Keyboard) {
    cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    cordova.plugins.Keyboard.disableScroll(true);
  };
  if(window.StatusBar) {
    StatusBar.styleDefault();
  }
  db = window.sqlitePlugin.openDatabase({name: 'myDbName.db', location: 'default'});
  if (window.Connection) {
    if (navigator.connection.type !== Connection.NONE) {
      databaseFactory.createTables(db);
      MyService.getStuffFromAPI().then(function(result) {
        for (var index = 0; index < result[0].campaigns.length; index++) {
          databaseFactory.insertIntoTable(db, result[0].campaigns[index]);
        }
        var selectResult = databaseFactory.selectFromCampaigns();
        console.log(selectResult); //This log comes earlier than the above inserts could finish.
      }, function(result) {
        console.log(result);
      });
    }
  }
});

不管怎样,INSERT运行良好,我确实检查过了。

我知道datebase.transaction是异步的,所以也尝试过使用单个db.executeSQL命令,但即使在向工厂添加$q resolve,reject时也遇到了同样的问题。我真的需要一些帮助,谢谢!

每次插入都返回一个promise。在一系列承诺中遵守这些承诺,并使用$q.all等待所有承诺完成。

示例:用于插入对象的工厂方法

function insert(object){
    var deferred = $q.defer(); //IMPORTANT
    var query = "INSERT INTO objectTable (attr1, attr2) VALUES (?,?)";
    $cordovaSQLite.execute(db, query, [object.attr1, object.attr2]).then(function(res) { //db object is the result of the openDB method
        console.log("INSERT ID -> " + res.insertId);
        deferred.resolve(res); //"return" res in the success method
    }, function (err) {
        console.error(JSON.stringify(err));
        deferred.reject(err); //"return" the error in the error method
    });
    return deferred.promise; //the function returns the promise to wait for
}

然后,在每个插入中:

promises.push(yourService.insert(obj).then(function(result){ //"result" --> deferred.resolve(res);
    //success code 
}, function(error){ //"error" --> deferred.reject(err);
    //error code
}));

最后:

$q.all(promises).then(function(){//do your selects}, function(err){//error!});

希望能有所帮助。

有关$q和$q.all的更多信息:https://docs.angularjs.org/api/ng/service/$q#所有

还有另一个例子:https://www.jonathanfielding.com/combining-promises-angular/

问题是我使用database.transaction(function (tx){})的方式,因为它本身是一个异步函数,在函数体内部,我可以进行同步CRUD操作,它们将按顺序进行
app.js(已修复)

ionic.Platform.ready(function () {
  if (window.cordova && window.cordova.plugins.Keyboard) {
    cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    cordova.plugins.Keyboard.disableScroll(true);
  };
  if(window.StatusBar) {
    StatusBar.styleDefault();
  }
  db = window.sqlitePlugin.openDatabase({name: 'MagicalWonder.db', location: 'default'});
  if (window.Connection) {
    if (navigator.connection.type !== Connection.NONE) {
      MyService.getMyPreciousData().then(function(result) {
        db.transaction(function(tx) {
          databaseFactory.createTable(tx);              
          for (var index = 0; index < result[0].campaigns.length; index++) {
            databaseFactory.insertIntoTable(tx, result[0].myPreciousData[index]);
          }
          // HERE I CAN MAKE THE SELECT REQUESTS
        }, function(error) {
          console.log('transaction error: ' + error.message);
          database.close();
        }, function() {
          console.log('transactions successfully done.');
        });
      }, function(result) {
        console.log(result);
      });
    }
  }
});

工厂法(固定)

factory.insertIntoTable = function (tx, data) {
  var sqlCommand = 'INSERT INTO wanders (' +
                   'id, ' +
                   'magic_spell) values (?,?)';
  tx.executeSql(sqlCommand, [data.id, data.magic_spell], function (tx, resultSet) {
      console.log('Success: insertIntoBookOfWonder');
  }, function (tx, error) {
    console.log('SELECT error: ' + error.message);
  });
};

最新更新