使用请求承诺在 Electron 中链接 HTTP 请求

Chaining HTTP requests in Electron using request-promise

更新

好的,所以我解决了。使用 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)
    })

整个代码块在调用时通过遍历文件的每一行执行数千次。第一个请求被连续触发,但这似乎显着 block/throttle 支持第二个请求,它只被定期调用。

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

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

        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)
                 })

         });

如果您不想一次触发每个请求(阅读您所做的评论似乎就是这种情况),那么不要 运行 并行执行所有请求:

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

您可以在 运行 fs.createReadStream:

之前创建一个空数组
var requests = [];

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

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

然后你可以运行它串联:

async.series(requests);

使用 async 模块。

只需确保 next() 在正确的时间被调用,例如在给定承诺链的最后 .then() 回调中。

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

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

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

然后在您的 each 回调中:

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

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

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

例子

为了从评论中回答你的问题,这里有一种构造函数数组的方法。

如果这是您的原始代码:

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);

希望对您有所帮助。