1

Node.js + Express + nodejs-sqlite3 を使用して、送信時に slite3 データベースに新しい行を挿入するフォームを作成しています。クエリの成功時に、特定の応答を書きたいと思います。

したがって、小さな大きな問題は次のとおりです。sqlite3.run() のコールバック関数内で、表示する html を格納する文字列を変更します。

クロージャーについて読み、オブジェクトにメソッドを渡して独自の属性を変更しました。しかし、それは機能していないようです。オブジェクトの属性とメソッドを渡しますが、コールバック関数が終了しても変更は残りません。オブジェクトはコピーではなく参照として渡されると読みました。

これはコードです:

app.post("/insert.html", function(req, res){
    function TheBody(){
        this.html = "";
        this.msg = "";
        this.num = "";
    }
    TheBody.prototype.add = function(string){
        this.html = this.html + string;
    }
    var body = new TheBody();

    body.msg = req.body.message;
    body.num = req.body.number;

    var insertCallback = function(data){
        return function(err){
            if( err != null){
                console.log("Can't insert new msg: " + err.message);
                data.add("ERROR-DB");                                               
            } else {
                console.log("Ok. Inserted: " + data.msg);
                console.log(data.html);
                data.add("OK - MSG: "+data.msg+" NUM: "+data.num);
                console.log(data.html);
            }
        };
    };                                                                                   

    var db = new lite.Database('database.db');
    var query = "INSERT INTO outbox (message, number) VALUES (?, ?)";
    db.run(query, [body.msg, body.num], insertCallback(body) );

    res.setHeader('Content-Type', 'text/html');
    res.setHeader('Content-Length', body.html.length);
    res.end(body.html);
}

サーバー側で私は見るでしょう

Ok. Inserted: TestString
[Blank space since data.html still has no information]
OK - MSG: TestString NUM: TestNumber [Showing that indeed was modified inside the function]

ただし、クライアント側でres.end(body.html);は空の文字列が送信されます。オブジェクトが参照として渡されていません。

コードに欠けているもの、およびコールバック匿名関数内の文字列変数を変更するために必要なより簡単な代替手段は何ですか?.

response.write()もっと単純であれば、関数に直接書き込むことができることはすでに知っています。しかし、コールバック内で使用する場合にのみ機能することを発見しました。それ以外の場合 (現在のように外部にある場合) 、使用できるようになるresponse.end()前にバッファーが閉じられるという競合状態になります。sqlite3.run()response.write()

-------- 回答済み --------

Justin Bicknell が示唆し、George P. が確認したように、Nodejs-sqlite3 関数は非同期で実行されます。そのため、コールバックが呼び出される前にクライアントへのストリームを終了していたため、何も出力されていませんでした。これは論理的な問題ではなく、「これはSPART-nodejsなので、イベントに応じて記述してください」という問題でした。この種のプログラミングは複雑だと思いましたが、nodejsを使用するように言われたのは私だけでした。データベースのクエリの順序をどのように変更できるか疑問に思っている方のために、nodejs-sqlite3 関数は、次のクエリをチェーンするために使用されるデータベース オブジェクトを返します。

処理された event ごとに一度だけクライアントに情報を出力していたので、結果のオブジェクトは次のように終了しました。

function TheBody(response){
    this.response = response;
}
TheBody.prototype.printAll = function(string){
    this.response.setHeader('Content-Type', 'text/html');
    this.response.setHeader('Content-Length', string.length);
    this.response.end(string);
} 

すべてのコードを多くの res.setHeader() 行で乱雑にすることを好みます。

4

1 に答える 1

2

node-sqlite3 メソッドは、デフォルトで、並行して(非同期で) 実行されます。これは、コードが次のタイムラインを通過していることを意味します。

  1. あなたのコード呼び出しdb.run(...)
  2. あなたのコード呼び出しres.end(...)
  3. db.runコールバックを完了して呼び出します。

これは、ここ SO に関する膨大な数の質問の源であるため、妥当な時間内にここに書くことができる何よりも優れた回答をほぼ確実に見つけることができます。

ここから始めます:非同期 Javascript 実行はどのように行われますか? returnステートメントを使用しないのはいつですか?

于 2013-01-21T21:53:40.110 に答える