具有异步请求的 NodeJS
NodeJS with Async requests
我遇到了Node JS初学者和异步请求的传统问题。
我有用户生成的未知数量的 URL,随后存储在我的 Node JS 服务器上的数组中。Node JS 服务器必须遍历这些 URL,依次向每个 URL 发出请求。它必须按顺序执行此操作,并且必须等待每个响应,然后再移动到下一个 URL(当将发出新请求时)。最终结果应该是所有响应(恰好是 JSON)的顺序集合,作为 JSON 对象很好地存储在一起,然后在准备就绪时可以将其发送回客户端。
我认为我应该使用 async
NodeJS 库,并且我已经在使用needle
来发出请求。
URLs = ["http://a", "http://s", "http://d"];
async.eachSeries(URLs, function (URL, callback) { ..... });
我不清楚如何使用异步来确保 Needle 请求已完成,并在移动到下一个 URL 请求之前相应地存储该响应。下面是我的针头请求示例。
needle.get(URL, options, function(error, response, body){ ... });
欢迎部分或全部解决整个问题。
有了承诺,你可以用:
var Promise = require("bluebird");
var get = Promise.promisify(needle.get, needle);
var URLs = ["http://a", "http://s", "http://d"];
var current = Promise.fulfilled();
Promise.map(URLs, function (URL) {
current = current.then(function () {
return get(URL);
});
return current;
}).map(function(responseAndBody){
return JSON.parse(responseAndBody[1]);
}).then(function (results) {
console.log(results);
}).catch(function (e) {
console.error(e);
});
作为奖励,当网站具有无效的 json 或响应错误消息/空正文时,您的服务器不会崩溃。手写时,您需要手动尝试捕获,但承诺处理catch()
中的两种错误。由于 url 是由用户提供的,因此如果您不将手动 try-catch 添加到非承诺代码中,它们可以轻松地 DoS 您的服务器。
这里有两个示例,一个是使用 async.eachSeries
逐个保存结果,另一个是使用 async.mapSeries
收集所有结果,然后一次保存所有结果
URLs = ["http://a", "http://s", "http://d"];
function iterator1(URL, done){
var options = {};
needle.get(URL, options, function(error, response, body){
if(error){ return done(error) };
processAndSaveInDB(body, function(err){
if(err){ return done(err) };
done(null);
});
});
};
async.eachSeries(URLs
, iterator1
, function (err){
// global callback for async.eachSeries
if(err){
console.log(err)
} else {
console.log('All Needle requests successful and saved');
}
});
// Here is a similar technique using async.map, it may be more suitable
function iterator2(URL, done){
var options = {};
needle.get(URL, options, function(error, response, body){
if(error){ return done(error) };
done(null, body);
});
};
async.mapSeries(URLs
, iterator2
, function (err, results){
// global callback for async.mapSeries
if(err){
console.log(err)
} else {
console.log('All Needle requests successful');
// results is a 1 to 1 mapping in order of URLs > needle.body
processAndSaveAllInDB(results, function(err){
if(err){ return done(err) };
console.log('All Needle requests saved');
done(null);
});
}
});
我不清楚如何使用异步来确保 Needle 请求已完成,并在移动到下一个 URL 请求之前相应地存储该响应。
异步函数的series
变体可以解决这个问题;您只需确保在准备好继续之前不要调用迭代器函数的done
回调。实际上,这意味着将调用done
放在最内在的回调中(例如,您的 Needle 回调)
- 如何解压缩NodeJS请求's模块gzip响应体
- NodeJS请求模块-http上的body.IncomingMessage
- nodejs:请求jsmultipart二级文件和JSON.stringify
- Nodejs请求之后是请求同步问题
- 点击按钮从服务器nodejs请求数据
- 在循环完成 nodejs 请求之前执行回调
- 对 Expressjs / Nodejs 请求 - 响应处理感到困惑
- GiantBomb API 请求获取 HTML 而不是 JSON,Nodejs 请求模块
- nodejs 请求 - toString 失败 - 大文件的缓冲区大小问题 (maxBufferSize)
- NodeJS请求 - 总是返回econnrefused
- NodeJS请求多个api端点
- dojo/使用NodeJS请求一个png图像数组缓冲区,并将图像返回给客户端
- 如何解析nodejs请求中的url参数
- 从NodeJS请求获取主机
- 我如何使用NodeJs请求GET模块发送cookie
- 如何执行nodejs请求模块
- Nodejs请求返回错误行为
- NodeJS请求POST图标
- Nodejs请求模块返回XML的Facebook图API FQL查询,我需要JSON
- 从Nodejs请求中提取POST参数