Ban*_*man 1 foreach asynchronous node.js requestjs
我是node.js(和request.js)的新手.我想从不同的路径特定URL获得一个网站的机身背部(在下面的例子中http://www.example.com/path1,http://www.example.com/path2等. )并使用键/值映射(下面的siteData [path])将此数据记录在对象中.
var request = require('request'),
paths = ['path1','path2','path3'],
siteData = {},
pathLength = paths.length,
pathIndex = 0;
paths.forEach((path) => {
var url="http://www.example.com/"+path;
request(url, function(error, response, html){
if(!error){
siteData[path] = response.body;
pathIndex++;
if(pathIndex===pathLength){
someFunction(siteData);
}
}
});
function someFunction(data){
//manipulate data
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
(node) warning: possible EventEmitter memory leak detected. 11 unpipe listeners added. Use emitter.setMaxListeners() to increase limit.我尝试链接,request(url, function(...){}).setMaxListeners(100);但这不起作用.谢谢你的帮助!
Som*_*ens 10
看起来Promise是在这里完成工作的正确工具.我们将创建一个Promise在作业完成时解决的新对象,而不是回调.我们可以说"一旦你完成了,就做一些更多的东西"与.then运营商:
var rp = require('request-promise');
rp('http://www.google.com')
.then((htmlString) => {
// Process html...
});
Run Code Online (Sandbox Code Playgroud)
(如果出现任何问题,承诺拒绝并直接进入.catch)
someFunctionThatErrors('Yikes!')
.then((data) => {
// won't be called
})
.catch((err) => {
// Will be called, we handle the error here
});
Run Code Online (Sandbox Code Playgroud)
我们有很多异步任务要做,所以只有一个承诺不起作用.一种选择是将它们串联在一起,如下所示:
rp('http://www.google.com')
.then((htmlString) => rp('http://someOtherUrl.com'))
.then((otherHtmlString) => {
// and so forth...
Run Code Online (Sandbox Code Playgroud)
但这会失去一些异常的异常 - 我们可以并行完成所有这些任务.
var myRequests = [];
myRequests.push(rp('http://www.google.com').then(processStuff).catch(handleErr));
myRequests.push(rp('http://someOtherUrl.com').then(processStuff).catch(handleErr));
Run Code Online (Sandbox Code Playgroud)
......男孩看起来很难看.所有这一切都有一个更好的方法 - Promise.all()(你使用箭头功能,所以我认为原生Promise也适合你).它接受一系列promise并返回一个promise,当所有数组的promise都完成执行时它将解析.(如果其中任何一个错误,它会立即拒绝).该.then函数将被赋予一个数组,表示每个promise所解析的值.
var myRequests = [];
myRequests.push(rp('http://www.google.com'));
myRequests.push(rp('http://someOtherUrl.com'));
Promise.all(myRequests)
.then((arrayOfHtml) => {
// arrayOfHtml[0] is the results from google,
// arrayOfHtml[1] is the results from someOtherUrl
// ...etc
arrayOfHtml.forEach(processStuff);
})
.catch(/* handle error */);
Run Code Online (Sandbox Code Playgroud)
不过,我们必须手动调用.push我们想要访问的每个链接.那不行!让我们用一个漂亮的技巧来Array.prototype.map迭代我们的数组,依次操纵每个值并返回一个由新值组成的新数组:
var arrayOfPromises = paths.map((path) => rp(`http://www.example.com/${path}`));
Promise.all(arrayOfPromises)
.then((arrayOfHtml) => arrayOfHtml.forEach(processStuff))
.catch(function (err) { console.log('agh!'); });
Run Code Online (Sandbox Code Playgroud)
更清晰,更容易的错误处理.
| 归档时间: |
|
| 查看次数: |
5104 次 |
| 最近记录: |