使while循环同步

Posted

技术标签:

【中文标题】使while循环同步【英文标题】:Making the while loop synchronous 【发布时间】: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
);

【问题讨论】:

github.com/caolan/async#series 关于您的编辑,您必须在请求回调中调用 next() 【参考方案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 请求。

以上是关于使while循环同步的主要内容,如果未能解决你的问题,请参考以下文章

使 continue 语句在 do while 循环中工作

如何使用C中的while循环使程序无限重启

R quantstrat 代码中的 While 循环 - 如何使其更快?

Python while循环语句

(JavaScript) 为啥 while 循环中的“if”中的 continue 语句会使浏览器崩溃?

在while循环中使用if语句使R跳过某些索引值