Javascript nodejspromise库是如何为多个承诺工作的?

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

最近,我在nodejs中使用“promise”制作了一个webscraper。我为我想要刮取的每个url创建了一个承诺,然后使用all方法:

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()
是一个承诺数组。它知道绝对的