【问题标题】:minimal node.js synchronous wait on http requesthttp请求的最小node.js同步等待
【发布时间】:2016-05-20 07:11:07
【问题描述】:

考虑一个 node.js 循环来触发 http 请求,如下所示:

var http = require('http');

function sendOne(opts, body)
{
    var post_options = {
...
    }

    var sender = http.request(post_options, function(res) {
        // process response
    });

    sender.write(body)
    sender.end()
    return sender;
}

for( var i =0; i < maxUploadIterations; i++)
{
    var body = // construct payload
    var sent = sendOne(opts, body);
    // somehow wait on sent...
}

请注意,http.request 对象具有指定用于处理响应的回调函数。我的问题是如何使用内置的 Node 原语同步等待从 sendOne 返回的“Sent”对象。

我了解 Express 和 Futures 等多个框架可以处理此问题,但我想了解原始行为而不是使用“魔术”框架。

是否可以像这样接受“已发送”并在其上放置一个处理程序:

var sent = ...
sent.on("complete", function() { ... } );

?

如果是这样,究竟是哪个处理程序以及如何用它格式化循环?

【问题讨论】:

  • 您可以做的一件事是将其包装在Promise 中。我知道你说过你不想要一个框架,但 Promises 是 ES6 的一部分,现在是 node.js 的一部分。
  • 我同意@zero298 但你也可以看看this问题中提到的sync-request的源代码。
  • 你真的要进行同步请求还是想知道如何等待异步操作?它们不是一回事。
  • 我想知道如何等待异步操作。理想情况下,我想知道如何对任意异步操作集合进行同步等待。
  • 另外,我希望能够改变该集合的内容。所以我不一定要全部解雇并等待。我希望能够解雇 N 并等待。然后触发 N+1...K 并等待,等等。因此,我试图了解原语节点提供的同步以及如何使用它来构建迭代结构。

标签: javascript node.js


【解决方案1】:

另一种选择,使用老式回调...虽然 promise 可能更简洁。

var http = require('http');

function sendOne(opts, body, next) {
    var post_options = {
        // ...
    };

    var sender = http.request(post_options, function (res) {
        // process response
        next();
    });

    sender.write(body);
    sender.end();
}

var maxUploadIterations = 100;
function next(index) {
    // termination condition
    if (index >= maxUploadIterations) {
        return;
    }

    // setup next callback
    var nextCallback = next.bind(null, index + 1);

    // get these from wherever
    var opts = {};
    var body = {};
    sendOne(opts, body, nextCallback);
}

next(0);

如果你之后有更多的工作要做,你可以改变终止条件来调用别的东西,而不是返回。

【讨论】:

  • 我认为这已接近满足我的要求。看起来我将使用 maxUploadIterations 深度的“下一个”调用堆栈结束。节点会清理尾递归,还是当 maxUploadIterations 变得非常大时我需要注意这一点?
  • 我对 ES6 中的 tall 调用优化了解不多,我猜你需要将其展平为单个函数以检测尾递归。我不确定它有多聪明……不过这并不难,我主要为了可读性而拆分了函数。
  • @Brad 我在 NodeJS 5.5.0 中使用 NPM 堆栈跟踪模块 (npmjs.com/package/stack-trace) 进行了快速测试。它似乎保持锁定在 3 的舒适深度,因此 NodeJS 正在使用尾调用优化,或者它是工作调度程序的工件。我使用setTimeout 代替http.request 进行测试。它的行为可能不同,尽管我怀疑任何调度异步工作的功能都会相同。您必须在您的环境中自己测试它。
猜你喜欢
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2018-02-14
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 2019-09-30
相关资源
最近更新 更多