9

考虑:

var globalvar;

function viewyearmain() {
  db.transaction(function (tx) 
  {
    tx.executeSql('SELECT * FROM BUDGET WHERE holdingtype="month"', [], function (tx, results) 
    {
       var len = results.rows.length;
       msg = len;
       globalvar = msg;
    }, null);

  });

  if (globalvar>0)
  {
    alert("ROWS FOUND");
  }
  else
  {
    alert("ROWS NOT FOUND");
  }
}

出现问题是因为在到达语句ROWS NOT FOUND时事务尚未完成。if

4

6 回答 6

6

异步回调不是同步的,无论您想要多少。

只需将依赖于结果的所有代码移动到回调中:

var globalvar;

function viewyearmain() {
  db.transaction(function (tx) 
  {
    tx.executeSql('SELECT * FROM BUDGET WHERE holdingtype="month"', [], function (tx, results) 
    {
       var len = results.rows.length;
       msg = len;
       globalvar = msg;
       if (globalvar>0)
       {
         alert("ROWS FOUND");
       }
       else
       {
         alert("ROWS NOT FOUND");
       }
    }, null);

  });
}

或者,将其移动到第二个函数中,并从回调中调用它。

于 2013-02-10T21:53:03.177 回答
5

如今,您可以像这样利用async / await和承诺:

async function alertResult() {
  const rows = await viewyearmain();
  if (rows.length) {
    alert("ROWS FOUND");
  } else {
    alert("ROWS NOT FOUND");
  }
}

function viewyearmain() {
  return new Promise(resolve => {
    db.transaction(function(tx) {
      tx.executeSql(
        "SELECT * FROM BUDGET WHERE holdingtype = ?;", ["month"],
        function(tx, result) { resolve(result.rows); },
        null
      );
    });
  });
}
于 2020-05-23T08:24:46.993 回答
2

我迟到了几年,但考虑到这个问题从未被直接回答,我想我会投入两分钱,并添加一些建议!

首先,如果您正在阅读本文,您可能不应该使用 WebSQL。它已被弃用,取而代之的是 IndexedDB,此时它是 W3C 标准轨道上的唯一数据库。

如果出于某种原因,您打算使用 WebSQL,并且您可以享受其异步 API 提供的好处(其中一些在 John Fowler 的回答中提到),那么您应该知道它的规范还定义了一个同步 API .

所以是的,有一种方法可以在 WebSQL 中同步执行语句,前提是您正在开发的浏览器已经实现了同步 API。

如果您不介意处理与同步接口一样简单的异步接口,请查看BakedGoods

有了它,执行您的查询就像这样简单:

bakedGoods.getAll({
    filter: "valueObj.holdingType === 'month'",
    storageTypes: ["webSQL"],

    //Contains database configuration data and operation preferences
    options: optionsObj,

    complete: function(byStorageTypeResultDataObj, byStorageTypeErrorObj){}
});

其简单的界面和无与伦比的存储设施支持是以缺乏对某些存储设施特定配置的支持为代价的。例如,它不支持在具有多列主键的 WebSQL 表中进行存储操作。

因此,如果您大量使用这些类型的功能,您可能想看看其他地方。

哦,为了完全透明,BakedGoods 由您真正维护 :) 。

于 2016-07-11T14:15:09.213 回答
1

据我所知,WebSQL 不支持同步 SQL 语句。这通常是一件好事,因为您不希望 SQL 处理中断或冻结您的用户界面。因此,CL. 的答案为处理查询结果提供了正确的异步机制。

但是,如果您真的需要同步 SQL 查询,请查看 WebSQL 替代方案: SequelSphere - 一个 HTML5/JavaScript SQL 关系数据库

它是 100% JavaScript,所以它可以在任何浏览器和任何平台上运行。此外,它将数据存储在 IndexedDB 或 LocalStorage 中。它还包含许多 WebSQL 没有的花里胡哨:JSON 集成、更改跟踪器、用户定义的 SQL 函数、同步 SQL 处理等。由于 WebSQL 标准已被弃用,我认为这是一个很好的替代方案。

完全披露:我喜欢 WebSQL,但我嫁给了 SequelSphere。

于 2013-02-11T14:58:09.273 回答
1

不太同步 - 但这是一个开始。

创建一个辅助函数以在 Promise 中执行查询

const executeSql = (query, params) => new Promise ( (resolve, reject) => {
  tx.executeSql(query, params, resolve, reject);
};

然后从异步函数运行时,您可以使用“等待”关键字

const myFunc = async () => {
   let result = await executeSql("SELECT * FROM BUDGET WHERE holdingtype=?", ["month"]);
}

但是,您可能对事务的结果有疑问,因为一旦 Promise 实现,对象可能会取消引用。

const executeSql = (query, params) => new Promise ( (resolve, reject) => {
    tx.executeSql(query, params, 
        (tx, results) => {
            var items = [];
            if(results.rows.length)
            {
                var max = results.rows.length;
                for (var x = 0; x < max; x++) items.push(results.rows.item(x))
            }
            resolve(items)
        }, reject)
    })
于 2020-04-06T05:47:24.857 回答
0

现在有点晚了,但值得一提的是……您不能使调用同步,但是您可以使用诸如Async之类的库来简化代码。这可能看起来有点矫枉过正,但如果您需要连续执行 3 或 4 条语句,它可以使您的代码更易于阅读。

async.waterfall([
    function(callback){
        db.transaction(function (tx) {
            tx.executeSql('SELECT * FROM BUDGET WHERE holdingtype="month"', [], 
                function (tx, results) {
                    var len = results.rows.length;
                    callback(null, len)
                }, 
                function(){
                    callback("An error occurred when reading data");
                }
            }); 
       });
    },
    function(len, callback){
        // Now do something with the length.
        console.log("The length is: " + len);
    }
]);
于 2015-10-08T19:34:20.183 回答