14

Haraka (smtp サーバー) プラグインに Node.js を使用するプロジェクトに取り組んでいます。

これは Node.JS で、コールバックに少し問題があります。この特定のコードをコールバックを使用するように変換できませんでした。

だから、これは私が持っているコードです:

exports.hook_data = function (next, connection) {
    connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
        var header = connection.transaction.header.get("header");
        if (header == null || header == undefined || header == '') return body_buffer;

        var url = 'https://server.com/api?header=' + header ;
        var request = require('request');
        request.get({ uri: url },
          function (err, resp, body) {
              var resultFromServer = JSON.parse(body);
              return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
          }
        );
    });
    return next();
}

リクエストのコールバックが継続するのを待たないため、このコードは機能しません。までにリクエストを終わらせる必要がありnext()ます;

要件は次のとおりです。

  1. の最後exports.hook_dataに返す必要がありnext()ます。しかし、それは要求の後にそれを返せばよいだけです。
  2. Bufferinを返す必要がadd_body_filterありますが、サーバーから取得した情報でバッファーを作成する必要があります。
  3. Get Request を作成するには、header内部にのみあるパラメーター ()を使用する必要がありますadd_body_filter

したがって、問題は、リクエストadd_body_filterを作成するために必要なパラメーターが 内にしかないため、前にリクエストを作成して結果をコールバック内に入れることができないことadd_body_filterです。

アドバイスをお願いします。

4

5 に答える 5

0

JavaScript は本質的に非同期です。非同期は、ノンブロッキング コードの機能を提供するプログラミング パターンです。つまり、コードの特定の行を実行するために停止したり、別の関数やプロセスに依存したりしません。参照:コードメンターの記事

ウィキペディアより

Node.js は、リアルタイム Web アプリケーションのアプリケーションのスループットとスケーラビリティを最適化するように設計された、イベント駆動型アーキテクチャとノンブロッキング I/O API を提供します。

あなたは何ができますか?

  1. sleep/wait ie を使用するsetTimeout(非推奨)
  2. https://github.com/caolan/asyncのような非同期ライブラリを使用します(推奨)
  3. Qのようなプロミス ライブラリを使用する
于 2015-12-24T17:09:22.617 に答える
0

トランザクション オブジェクトヘッダー オブジェクトの Haraka マニュアルを見ると、ヘッダーが に依存しているとは思えませんadd_body_filter。また、コードは への依存関係を示していませんadd_body_filter。したがって、3 番目の要件は無効に見えます。

それを考えると、次の疑似コード(テストできないため)がうまくいくはずです。

exports.hook_data = function (next, connection) {
    var header = connection.transaction.header.get("header");
    if (header == null || header == undefined || header == '') {
        return next();

    var url = 'https://server.com/api?header=' + header ;
    var request = require('request');
    request.get({ uri: url },
        function (err, resp, body) {
            var resultFromServer = JSON.parse(body);
            connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
                return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
            });
            next();
        }
    );
}

Haraka マニュアルが Header の依存関係を強調していない場合、add_body_filterおよび/または実際の経験に基づいてそれを発見した場合は、Quy のアプローチが適しているようです。

next() v/s return next() をいつ使用するか迷っている場合

于 2015-12-23T13:03:05.787 に答える
0

私が使用するコードの各部分の優先順位を処理Qするには、いくつかの手順で使用できます。

  1. npm install q.

    var request = require('request');
    var Q = require('q');
    
    exports.hook_data = function () {
       var url, header;
       Q()
       .then(function(){
         connection.transaction.add_body_filter('', function(content_type, encoding, body_buffer) {
    
          header = connection.transaction.header.get("header");
    
          if (header == null || header == undefined || header == ''){return body_buffer;}
          url = 'https://server.com/api?header=' + header ;
    
       })
       .then(function(){
    
           request.get({ uri: url }, function (err, resp, body) {
    
               var resultFromServer = JSON.parse(body);
    
               return ChangeBuffer(content_type,encoding,body_buffer,resultFromServer);
           });
    
       })
    
    }
    

asyncシナリオでは、 for callbacks を使用するqことは、私が考える他の方法よりも優れています。

于 2015-12-24T16:58:09.767 に答える