【问题标题】:Making the while loop synchronous使while循环同步
【发布时间】:2013-03-31 21:34:44
【问题描述】:

我有一段代码

var page = 2;
var last_page = 100;
while(page <= last_page) {
  request("http://some_json_server.com/data?page=" + page, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      store_data(body)
    }
    page++;
  });                
}

我已经完成了以下操作,但实际上并没有检索任何内容。我这样做对吗?

var page = 2;
var last_page = 100;
while(page <= last_page) {
var async_arr = [];
async_arr.push(
  function(next) {
    request("http://some_api_url?page=" + page, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        store_data(body);
      }
    });
  }
);

async.series(
  async_arr, done
);

【问题讨论】:

标签: javascript node.js asynchronous


【解决方案1】:

您还可以将您的 while 循环包装在异步中,并在您的承诺解决/条件得到满足后中断...

    const request = require("request")

    ;(async()=>{

    let results = []
    while(true){
      await new Promise(resolve => {
        request('http://www.seanbehan.com/', (err, resp, body)=>{
          console.log(new Date, 'Downloading..')
          results.push(body)
          resolve(body)
        })
      })

      if(results.length >= 5){
        break
      }
    }

    console.log(results)
  })()

【讨论】:

    【解决方案2】:

    您正在寻找async.whilst()。此解决方案假设您实际上想要一个接一个地执行每个请求。正如@UpTheCreek 提到的(edit:我提到的评论已被编辑),可能可以异步执行此操作并使用async.parallel 跟踪每个结果。

    var page = 2,
        lastPage = 100;
    
    async.whilst(function () {
      return page <= lastPage;
    },
    function (next) {
      request("http://some_json_server.com/data?page=" + page, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          store_data(body)
        }
        page++;
        next();
      });
    },
    function (err) {
      // All things are done!
    });
    

    【讨论】:

    • 该死,我希望你已经回答了我刚才问的问题。我想这正是我想要的。
    【解决方案3】:

    使用while 你会得到一个繁忙的循环,这在 Node 中是反作用的。

    改为使其成为递归函数。每个调用都将在一个单独的刻度中完成。

    var page = 2;
    var last_page = 100;
    
    (function loop() {
        if (page <= last_page) {
            request("/data?page=" + page, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    store_data(body)
                }
                page++;
                loop();
            });
        }
    }());
    

    【讨论】:

    • +1 如果您不知道页数怎么办?你会如何处理这个@katspaugh
    • @TheGrayFox,响应应该以某种方式指示页数,或者只是不向您发送数据,以便您知道您不应该发出下一个请求。
    • 递归函数最终会耗尽你所有的内存并且你会超出你的调用栈大小。
    • @katspaugh 假设用例永远不会超过第 100 页,它可能不会导致任何问题,并且它的递归只发生在请求回调内部,它可能不会导致问题。如果您打算使用此模式,请注意一点。
    • 我认为您应该考虑使用 http 代理。 nodejs.org/api/http.html#http_new_agent_options我发现,通过将代理用作自定义请求池,您可以更好地控制大量 http 请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 2016-01-28
    相关资源
    最近更新 更多