首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何进行回调,要求它的子函数的信息。

问我如何进行回调,要求它的子函数的信息。
EN

Stack Overflow用户
提问于 2015-12-15 20:16:54
回答 5查看 489关注 0票数 14

我正在一个项目中工作,该项目将Node.js用于原坂 (一个smtp服务器)插件。

这是Node.JS,我在回调时遇到了一点小问题。我无法将这个特定的代码转换为使用回调。

所以,这就是我的代码:

代码语言:javascript
复制
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. 我需要在Buffer中返回一个add_body_filter,但我需要使用从服务器获取的信息创建缓冲区。
  3. 为了发出Get请求,我需要使用一个参数(header),该参数仅包含在add_body_filter中。

因此,问题是我无法在add_body_filter之前发出请求并将结果放入回调中,因为我需要的请求参数仅在add_body_filter中。

有什么建议吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-12-15 20:31:30

除非您愿意使用同步、阻塞函数,否则不可能满足已编号的需求。

我会检查每个需求背后的原因,看看你是否以不同的方式完成了你的目标。

从表面上看,只要看一下代码,我就会寻找一种方法来更改exports.hook_data的契约,以便您能够从request.get回调内部调用request.get。

票数 4
EN

Stack Overflow用户

发布于 2015-12-20 03:43:48

使用Async.js或承诺。

异步实现:

代码语言:javascript
复制
exports.hook_data = function (next, connection) {
  async.waterfall([
    function( done ) {
      connection.transaction.add_body_filter('', function( content_type, encoding, body_buffer ) {
        var header = connection.transaction.header.get("header");
        if ( header == null || header == undefined || header == '' ) {
          done(null, body_buffer);
        }
        done(null, header);
      });
    },
    function( header, done ) {
      var url = 'https://server.com/api?header=' + header;
      var request = require('request');
      request.get({ uri: url },
        function( err, resp, body ) {
          // do something if there's an error
          var resultFromServer = JSON.parse(body);
          done(null, ChangeBuffer(content_type, encoding, body_buffer, resultFromServer));
        }
      );
    }
  ], function( error, buffer ) {
    // do something if there's error
    next(buffer);
  });
}

这里有很多东西,我建议您阅读async.js#waterfall上的文档。本质上,它将每个异步调用分解为on函数块,并等待它返回,然后再继续到下一个块。

同样,由于这些都是异步的,节点将这些任务提交给IO事件循环,并在那里处理(非阻塞)。当这个线程等待时,它可能会继续到下一个请求,而这个请求正在等待。

票数 1
EN

Stack Overflow用户

发布于 2015-12-23 13:03:05

查看事务对象 & 标头对象的Haraka手册,我发现add_body_filter上没有任何头的依赖关系。而且,您的代码不显示对add_body_filter的任何依赖。所以你的第三个要求看起来是无效的。

考虑到这一点,我认为遵循伪代码(因为我无法测试)应该对您有用。

代码语言:javascript
复制
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返回next()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34298589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档