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

时间:2016-09-22 08:15:20

标签: javascript node.js electron chaining

更新

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

         });

1 个答案:

答案 0 :(得分:2)

如果您不想立即触发每个请求,这似乎是在阅读您所做的评论的情况下,而不是与以下内容并行运行:

.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()在应该的时候被调用。最后你可以使用其他数字来代替并行完成一定数量的请求。)

然后在你的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);

希望它有所帮助。