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);

  });
}

または、それを2番目の関数に移動し、コールバックから呼び出します。

于 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

私は2、3年遅れていますが、質問に直接答えられなかったことを考えると、2セントを投入し、いくつかの提案を追加すると思いました。

まず、これを読んでいる場合は、おそらくWebSQLを使用するべきではありません。これは廃止され、IndexedDBが採用されました。これは、現時点でW3C標準トラック上の唯一のデータベースです。

何らかの理由でWebSQLを使用することに熱心であり、非同期APIが提供する利点(その一部はJohn Fowlerの回答に記載されています)なしで生きることができる場合は、その仕様が同期APIも定義していることを知っておく必要があります。

そうです、開発しているブラウザが同期APIを実装していれば、WebSQLでステートメントを同期的に実行する方法があります。

同期インターフェースと同じくらい単純な非同期インターフェースを扱ってもかまわない場合は、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 /JavaScriptSQLリレーショナルデータベースを確認してください。

これは100%JavaScriptであるため、任意のブラウザーおよび任意のプラットフォームで実行されます。さらに、データはIndexedDBまたはLocalStorageのいずれかに格納されます。また、JSON統合、変更トラッカー、ユーザー定義SQL関数、同期SQL処理など、WebSQLにはない多くの機能が含まれています。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);
};

次に、非同期関数から実行する場合は、「await」キーワードを使用できます

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 に答える