Javascript nodejspromise库是如何为多个承诺工作的?
最近,我在nodejs中使用“promise”制作了一个webscraper。我为我想要刮取的每个url创建了一个承诺,然后使用all方法:Javascript nodejspromise库是如何为多个承诺工作的?,javascript,node.js,parallel-processing,web-scraping,promise,Javascript,Node.js,Parallel Processing,Web Scraping,Promise,最近,我在nodejs中使用“promise”制作了一个webscraper。我为我想要刮取的每个url创建了一个承诺,然后使用all方法: var fetchUrlArray=[]; for(...){ var mPromise = new Promise(function(resolve,reject){ (http.get(...))() }); fetchUrlArray.push(mPromise); } Promise.all(fetchUrl
var fetchUrlArray=[];
for(...){
var mPromise = new Promise(function(resolve,reject){
(http.get(...))()
});
fetchUrlArray.push(mPromise);
}
Promise.all(fetchUrlArray).then(...)
有数千个URL,但只有少数几个超时。我得到的印象是,它一次并行处理5个承诺。
我的问题是promise.all()到底是如何工作的。它是否:
逐个调用每个承诺并切换到下一个,直到前一个承诺得到解决。
或者在过程中从阵列中批量做出承诺。
还是说它会放弃所有的承诺
在nodejs中解决这个问题的最佳方法是什么。因为就目前而言,我可以用Java/C更快地解决这个问题。首先,我要澄清一点:承诺确实代表了计算的未来结果,而不是其他。它不表示任务或计算本身,这意味着它不能被“调用”或“激发”
您的脚本确实立即创建了所有数千个承诺,并且每个创建都会立即调用http.get
。我怀疑http
库(或它所依赖的东西)有一个连接池,限制了并行请求的数量,并隐式地延迟了其余的请求
Promise.all
不做任何“处理”-它不负责启动任务和解决传递的承诺。它只听它们,检查它们是否都准备好了,并为最终结果返回一个承诺。首先,需要澄清的是:承诺确实代表了计算的未来结果,而不是其他。它不表示任务或计算本身,这意味着它不能被“调用”或“激发”
您的脚本确实立即创建了所有数千个承诺,并且每个创建都会立即调用http.get
。我怀疑http
库(或它所依赖的东西)有一个连接池,限制了并行请求的数量,并隐式地延迟了其余的请求
Promise.all
不做任何“处理”-它不负责启动任务和解决传递的承诺。它只会听取他们的意见,检查他们是否都准备好了,并返回最终结果的承诺。我会这样做
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
就我个人而言,我不太喜欢承诺。我认为API非常冗长,生成的代码很难阅读。下面定义的方法会产生非常简单的代码,并且更容易立即理解发生了什么。至少在国际海事组织
这是我为解决这个问题而创造的一个小东西
您可以这样使用它
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
此功能的好处
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
- 没有外部依赖项或beta API
- 可在要在其上执行异步任务的任何阵列上重用
- 非阻塞,正如您对node所期望的那样
- 可以很容易地适应并行处理
- 通过编写您自己的实用程序,您可以更好地了解这种事情是如何工作的
如果您只想获取一个模块来帮助您,请查看和了解方法。我会这样做
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
就我个人而言,我不太喜欢承诺。我认为API非常冗长,生成的代码很难阅读。下面定义的方法会产生非常简单的代码,并且更容易立即理解发生了什么。至少在国际海事组织
这是我为解决这个问题而创造的一个小东西
您可以这样使用它
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
此功能的好处
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
- 没有外部依赖项或beta API
- 可在要在其上执行异步任务的任何阵列上重用
- 非阻塞,正如您对node所期望的那样
- 可以很容易地适应并行处理
- 通过编写您自己的实用程序,您可以更好地了解这种事情是如何工作的
如果您只是想获取一个模块来帮助您,请查看和了解该方法。您传递的内容
Promise.all()
是一系列承诺。它完全不知道这些承诺背后的原因。它所知道的是,这些承诺将在未来某个时候得到解决或被拒绝,它将创建一个新的主承诺,它将遵循您通过的所有承诺的总和。这是承诺的好处之一。它们是一种抽象,允许您协调任何类型的操作(通常是异步的),而不考虑它是什么类型的操作。因此,承诺与实际行动毫无关系。他们所做的只是监控行动的完成或错误,并在承诺后向这些代理报告。其他代码实际运行该操作
在您的特定情况下,您立即在一个紧密的循环中调用http.get()
,您的代码(与承诺无关)立即启动大量http.get()
操作。这些将以底层传输所能达到的速度被触发(可能受到连接限制)
如果您想让它们以串行方式或批量方式启动,比如说一次启动10个,那么您必须自己编写代码。承诺与此无关
您可以使用承诺来帮助您编写代码,让它们以串行方式或批处理方式启动,但这两种方式都需要额外的代码才能实现
该库是专门为并行运行而构建的,但在任何给定的时间都有最大数量的正在运行,因为这是一种常见的方案,在这种方案中,您的终端要么有连接限制,要么不想压倒接收服务器。您可能对该选项感兴趣,该选项允许您并行运行多个异步操作,但在任何给定时间都有最大数量的异步操作。您传递的
Promise.all()
是一个承诺数组。它知道绝对的