使用API​​调用阻塞nodejs

我不确定这是否是正确的方法,但我期待在for循环中创build10个API请求,并且我希望每个API请求都被阻止。 也就是说,要等到我收到响应而没有callback,然后再次遍历foor循环。 这是foor循环

for (var i=0; i< out.items.length; i++) { var object = makediffbotAPIcall(out.items[i]); console.log(object); } 

请求function如下

 function makediffbotAPIcall(item, array) { var url_to_send_diffbot = "string of url here"; request(url_to_send_diffbot, function (error, response, body) { if (!error && response.statusCode == 200) { var article_object = JSON.parse(body) var object = {"Title": article_object.title, "Url":article_object.url}; } }); return object; } 

这个代码的问题是对象没有及时返回foor循环来使用它。 我试图在makediffbotAPIcall函数的结尾放置一个setTimeout,但是这也不起作用。 任何build议,非常感谢。 谢谢!

有一个非常好的node.js库“async”来pipe理asynchronous环境中的控制stream。 对于这个特定的问题https://github.com/caolan/async#forEach系列版本,并在makediffbotAPIcall有一点修改使事情工作完全一样,因为你正在寻找所以这里是解决scheme

 async.forEachSeries(out.items,function(item,callback){ makediffbotAPIcall(item,out.items,function(object){ //here you will get either object or null callback(); }),function(err){ // this will be called when all array items will get processed }) function makediffbotAPIcall(item, array, callback) { var url_to_send_diffbot = "string of url here" request(url_to_send_diffbot, function (error, response, body) { if (!error && response.statusCode == 200) { var article_object = JSON.parse(body) return callback({"Title": article_object.title, "Url":article_object.url}) } else return callback(null); }) } 

我不知道第二个参数makediffbotAPIcall我假设你想传递完整的数组,所以我只是传递整个数组,如果不是你可以修改它的情况下,你想要的。

如果您有任何问题,请告诉我。

Async.js是一个很好的开始,还有其他类似的东西 – https://github.com/joyent/node/wiki/modules#wiki-async-flow

但是,请注意,“阻塞”代码在node / js中不是一个好主意。 这是一个单线程事件驱动的语言。 你不想阻塞代码,因为那么你的服务器,例如,将停止响应请求。 由于以上所述,大多数asnyc模式会要求您提供一个callback函数,有时也称为“下一个”,您需要在每个函数结束时调用该函数,以便调用下一个函数。

你需要来自async.js库的forEachSeries(arr,iterator,callback)。

它所做的是以非重叠顺序的方式迭代arr。 适合重复性任务按顺序执行。 一旦所有的迭代完成,callback被调用。 最好的部分是干净的,没有callback的麻烦。

你应该尝试从async.js的其他function。 这是一个伟大的图书馆,非常方便。

我发现在处理JS中的asynchronous问题时,通常会非常有用,可以暂时移动命名所有匿名函数,以便在显式传递时以及何时调用它们。

 function makediffbotAPIcall(item, array) { var url_to_send_diffbot = "string of url here" var receiveResponse = function (error, response, body) { if (!error && response.statusCode == 200) { var article_object = JSON.parse(body); var object = {"Title": article_object.title, "Url":article_object.url}; } } request(url_to_send_diffbot, receiveResponse); return object; } 

所以这里有一些问题。 第一,即使你的请求是同步的(这将是一个可怕的事情,对于旧的单线程JavaScript),这将无法正常工作,因为你在var object receiveResponse var object使用var object ,所以variables将不会在该函数外部可用!

对于这个特殊的问题,最简单的解决方法是在receiveResponse里面调用console.log(object) 。 假设你已经简化了一些更复杂的代码,可以使用各种模式。 每个请求在前一个请求之后顺序发生是重要的,还是可以并行运行并单独logging(可能不按顺序)? 基本上,你需要为makediffbotAPIcall添加一个callback参数,并用responseReceived object调用该函数,或者返回一个Promise对象,除非你已经使用了一个提供它们的框架/库,否则这可能是过度makediffbotAPIcall ,或者你真的需要大量的并行和/或顺序操作支持。

我重新读你是问题,它看起来像你想阻止行为,这是一个纯粹的JS解决scheme(无需lib = P)使用recursion:

 var i=0; var callNext = function(object){ if(i<out.items.length) { makediffbotAPIcall(out.items[i], callNext); } console.log(object); i++; } callNect("nothing to log for first obj"); function makediffbotAPIcall(item, array, callback) { var url_to_send_diffbot = "string of url here" var receiveResponse = function (error, response, body) { if (!error && response.statusCode == 200) { var article_object = JSON.parse(body); var object = {"Title": article_object.title, "Url":article_object.url}; callback(object); } } request(url_to_send_diffbot, receiveResponse); } 

这可以做一些整理(recursion的基本情况处理笨拙),但你并不总是需要一个库;)