【问题标题】:Chaining HTTP requests in Electron using request-promise使用 request-promise 在 Electron 中链接 HTTP 请求
【发布时间】:2016-09-22 08:15:19
【问题描述】:

更新

好的,所以我解决了。使用 highland.js 时,我需要一个 .done() 来完成流。

var requests = [];           
_(fs.createReadStream("small.txt", { encoding: 'utf8' }))
        .splitBy('-----BEGIN-----\n')
        .splitBy('\n-----END-----\n')
        .filter(chunk => chunk !== '')
        .each(function (x) {

            requests.push(function (next) {
                Helpers.Authenticate()
                    .then(function (response1) {
                        return Helpers.Retrieve();
                    })
                    .then(function (response2) {
                        return Helpers.Retrieve();
                    })
                    .then(function () {
                        next();
                    });
            });

        })}).done(function () {
        async.waterfall(requests);
    });

request 数组现在正在工作。


我在使用电子和链式承诺时遇到了一些问题。这是我在主进程中运行的代码。

var request = require('request-promise');
request.post(tppAuthenticate)
    .then(function (responseFromFirstPost) {
        var newoptions = tppRetrieveCertificate(responseFromFirstPost.APIKey)
        return request.post(newoptions) // The return is important
    })
    .then(function (responseFromSecondPost) {
        console.log(responseFromSecondPost)
    })

整个代码块通过遍历文件的每一行来执行数千次调用。第一个请求被连续触发,但这似乎显着阻止/限制了仅定期调用的第二个请求。

我希望按顺序调用整个块,但这似乎没有发生。

这是我的完整代码块,包括迭代:

        const _ = require('highland');
        const request = require('request-promise');

        fs.createReadStream(files[0], { encoding: 'utf8' }))
         .splitBy('-----BEGIN -----\n')
         .splitBy('\n-----END -----\n')
         .filter(chunk => chunk !== '')

         // .each(_.log);
         .each(function (x) {

             request.post(tppHelpers.Authenticate)
                 .then(function (responseFromFirstPost) {
                     const newoptions = tppHelpers.tppRetrieveCertificate(responseFromFirstPost.APIKey)
                     console.log(newoptions)
                     return request.post(newoptions) // The return is important
                 })
                 .then(function (responseFromSecondPost) {
                     console.log(responseFromSecondPost)
                     event.sender.send('selected-directory', responseFromSecondPost)
                 })

         });

【问题讨论】:

  • 您能否澄清一下:您是否希望第 2 行的请求在第 1 行的两个请求都完成后开始?我理解你的描述的方式,你似乎同时创建了数千个请求,这肯定会影响辅助请求。
  • @kraf 我也是这么读的:开始了一大堆请求,可能会压倒事件队列或网络,这意味着辅助请求将被严重延迟。
  • 基本上第一个和第二个响应是链接的,需要立即串联执行,否则API密钥超时。第二个请求正在执行但非常缓慢,它们被第一个请求阻止。希望这会让它更清楚。
  • 你是说我这里实际上有 3 个请求?
  • @user1513388 你说的是“整个代码块执行了几千次”。如果您不正确地执行此操作,您将启动数千个并发 HTTP 请求。你能展示一下你是如何实现迭代的吗?

标签: javascript node.js electron chaining


【解决方案1】:

如果您不想一次触发每个请求,这似乎是读取您创建的 cmets 的情况,那么不要并行运行所有请求:

.each(function (x) {
  // ...
});

您可以在运行 fs.createReadStream 之前创建一个空数组:

var requests = [];

并在您的 each 回调中创建函数以添加到您的数组中:

.each(function (x) {
  requests.push(function (next) {
    // ...
    next();
  });
});

然后您可以使用以下命令串联运行它:

async.series(requests);

使用async 模块。

只要确保 next() 在正确的时刻被调用,例如在给定的 Promise 链的最后一个 .then() 回调中。

另一种方法是使用async.queue:

var queue = async.queue(function(x, callback) {
  // 
  callback();
}, 1);

(这里确保在应该调用 callback() 的时候调用它。最后你可以使用其他数字代替 1 来并行完成一定数量的请求。)

然后在您的each 回调中:

.each(function (x) {
  queue.push(x);
});

有关详细信息,请参阅 async.queue 文档。 (感谢 robertklep 在 cmets 中提及 async.queue()。)

顺便说一句:您甚至在迭代中使用x 还是只是对输入的每一行提出一堆相同的请求?

示例

为了回答 cmets 的问题,这里有一种构造函数数组的方法。

如果这是您的原始代码:

yourStream.each(function (x) {
  doRequest1()
  .then(function (response1) {
    return doRequest2();
  })
  .then(function (response2) {
    return doRequest3();
  });
});

然后你可以用类似的东西来构造这个函数数组:

var requests = [];
yourStream.each(function (x) {
  requests.push(function (next) {
    doRequest1()
    .then(function (response1) {
      return doRequest2();
    })
    .then(function (response2) {
      return doRequest3();
    })
    .then(function () {   
      next();
    });
  });
});

您可以使用以下命令运行它们:

async.series(requests);

希望对你有帮助。

【讨论】:

  • async.queue() 对于这类事情也非常有用。
  • @rsp 谢谢你。我在这里仍然有点挣扎。这种异步的东西真的很痛苦,而且有很多不同的方法可以做到这一点。将使用 x,因为这就是我需要提供给我的 HTTP 请求的内容。
  • @rsp 你提到“创建函数以添加到你的数组”这些函数会是什么样子?
  • @rsp - 非常感谢。这里的问题是 request 在 .each 函数之外是不可访问的。
猜你喜欢
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多