0

控えめな Firefox アドオンを作成していますが、アドオン スクリプトの「フロー」内で使用される結果を取得する際に問題があります。

モジュールとして sqlite データベースのクエリを処理するコードがありますが、アドオン スクリプトの pagemod がそれを使用してコンテンツ スクリプトに渡すことができるように、その内部にコールバックを作成する方法がわかりません。

基本的にここに私が持っているものがあります:

  • main.js :
var pageMod = require("sdk/page-mod");
var self = require("sdk/self");
var myDbScript = require('./myDbScript');

pageMod.PageMod({
    include: "*.example.com/*",
    contentScriptFile:  [self.data.url('jquery-1.10.2.min.js'),
                        self.data.url('myContentScript.js')],
    onAttach: function(worker) {
        // Query the database on behalf of the content script
        worker.port.on('queryTheDB', function(message) {            
            // Get the data from the DB (é is some test value here)
            // Not working because asynchronous querying of the DB
            var resultFromDB = myDbScript.getResult(2);

            // Send the result to the content script
            worker.port.emit('hereIsYourResult', resultFromDB);
        });
    }
});
  • myDBScript.js
// Get required components
var {components} = require("chrome");
components.utils.import("resource://gre/modules/FileUtils.jsm");
components.utils.import("resource://gre/modules/Services.jsm");

// Some code to get the DB

// Create statement to retrieve country based on the IP
var statement = dbConnection.createStatement("SELECT col1, col2 FROM table WHERE col1 = :given_col1");

function getResult(submittedValue) {    
    // Bind parameters
    statement.params.given_col1 = submittedValue;   

    // Execute
    statement.executeAsync({
        handleResult: function(aResultSet) {
            for (let row = aResultSet.getNextRow();
                 row;
                 row = aResultSet.getNextRow()) {

            var resultFromDB = row.getResultByName("col2");
            }
        },

        handleError: function(aError) {
            print("Error: " + aError.message);
            return 'error';
        },

        handleCompletion: function(aReason) {
            if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
                print("Query canceled or aborted!");
                return 'canceledOrAborted';
            } else {
                // Sending the result to the add-on script so that it can
                // pass it to the content script
                notifyingTheAddonScript(resultFromDB);
            }
        }
    });
}

// Enable the use of the getResult function
exports.getResult = getResult;

問題は、結果の準備ができていることをアドオンスクリプトに認識させる方法がわからないことです。ご容赦ください、私はこれに慣れていません...

4

1 に答える 1

1

完全なソースがないため、テストできません。したがって、私が作ったエラーを自分で修正する必要があります;)

まず、コールバックを追加しましょう。

// @param {function(result, error)} callback
// Called upon query completion.
// if |error| is a string, then the query failed.
// Else |result| will contain an array of values. 
function getResult(submittedValue, callback) { // changed   
  // Bind parameters
  statement.params.given_col1 = submittedValue;   

  var rv = [], err = null; // added
  // Execute
  statement.executeAsync({
    handleResult: function(aResultSet) {
      for (let row = aResultSet.getNextRow();
        row;
        row = aResultSet.getNextRow()) {

        rv.push(row.getResultByName("col2")); // changed
      }
    },

    handleError: function(aError) {
      print("Error: " + aError.message);
      err = aError.message; // changed
    },

    handleCompletion: function(aReason) {
      if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
        print("Query canceled or aborted!");
        err = err || 'canceled or aborted'; // changed
      }
      callback(err ? null : rv, err); // replaced
    }
  });
}

このようなものを今すぐ使用しましょうpagemod

onAttach: function(worker) {
  // Query the database on behalf of the content script
  worker.port.on('queryTheDB', function(message) {            
    // Get the data from the DB (é is some test value here)
    // Not working because asynchronous querying of the DB
    myDbScript.getResult(2, function callback(result, error) {
      if (error) {
        worker.port.emit("hereIsYourError", error);
        return;
      }
      worker.port.emit("hereIsYourResult", result);
    });
  });
}

複数のクエリを起動しないように、いくつかの予防策を講じる必要がある場合があります。そうしても問題ありませんが、パフォーマンスが低下する可能性があります;)

コールバックはすでに のように見えるので、promise実際にはpromisesを使用することをお勧めします。おそらく、Sqlite.jsmモジュールとTask.jsmマジックを使用することもできます。

于 2013-10-19T01:38:29.610 に答える