我不确定这是否是正确的方法,但我希望在for循环中生成10个API请求,并且我希望每个API请求都被阻止。也就是说,等到我收到响应而不进行回调然后再次遍历foor循环。这是foor循环
for (var i=0; i< out.items.length; i++) {
var object = makediffbotAPIcall(out.items[i]);
console.log(object);
}
请求功能如下
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,但这也没有用。任何建议都非常感谢。谢谢!
答案 0 :(得分:4)
有一个非常好的node.js库“async”,用于管理异步环境中的控制流。对于这个特定的issuse https://github.com/caolan/async#forEach系列版本,并且在makediffbotAPIcall中有一些修改,使得工作正如您所寻找的那样,所以这里是解决方案
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的第二个参数我假设你想要传递完整的数组,所以我只是传递整个数组,如果不是这样你可以根据需要修改它。
如果您有任何疑问,请与我们联系。
答案 1 :(得分:1)
Async.js是一个很好的起点,还有其他类似的东西 - https://github.com/joyent/node/wiki/modules#wiki-async-flow
但请注意,“阻塞”代码在node / js中不是一个好主意。它是一种单线程事件驱动语言。您不希望阻止代码,因为您的服务器将停止对请求做出反应。 由于上述原因,大多数asnyc模式会要求您提供一个回调函数,有时称为'next',您需要在每个函数的末尾调用它,因此将调用行中的下一个函数。
答案 2 :(得分:0)
我发现在处理JS中的异步问题时,通常有用的是移动和名称所有匿名函数,暂时显示它们何时被传递以及何时调用。
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;
}
所以这里有一些问题。 1,即使你的请求是同步的(这对于糟糕的旧单线程javascript来说也是一件可怕的事情),这样做是行不通的,因为你在var object
内使用了receiveResponse
,因此该变量将不可用在那个功能之外!
对于此特定问题,最简单的解决方案是在console.log(object)
内调用receiveResponse
。假设您实际上已经简化了一些更复杂的代码,那么可以使用各种模式。重要的是每个请求在前一个请求之后顺序发生,还是可以并行运行并单独记录(可能不按顺序)?基本上,你需要向makediffbotAPIcall
添加一个回调参数,并在object
内用responseReceived
调用该函数,或者返回一个Promise对象,这可能是过度的,除非你已经是使用提供它们的框架/库,或者您确实需要大量支持并行和/或顺序操作。
我重新阅读了你的问题,看起来你想要阻止行为,这是一个纯粹的JS解决方案(没有lib需要= P)使用递归:
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);
}
这可以用一些整理(递归的基本情况是笨拙地处理)但你并不总是需要一个库;)
答案 3 :(得分:0)
你需要来自async.js库的forEachSeries(arr,iterator,callback)。
它的作用是以非重叠的顺序方式迭代arr。非常适合按顺序执行重复性任务。所有迭代完成后调用回调。最好的部分是干净利落,没有回调麻烦。
您应该尝试使用async.js中的其他函数。这是一个很棒的图书馆,非常方便。