很难理解节点中的 async.parallel

Posted

技术标签:

【中文标题】很难理解节点中的 async.parallel【英文标题】:Hard time uderstaning async.parallel in node 【发布时间】:2018-08-23 09:33:31 【问题描述】:

我在控制器中有这个功能

router.post('/', function(req, res, next) 
  if (req.user.isPremium == false) 
    // Free user - Single report
    let website = req.body.website0;
    let builtWithCall = `https://api.builtwith.com/free1/api.json?KEY=APIKEY&LOOKUP=$website`;
    let pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://$website&strategy=mobile&key=APIKEY`;
    // curl 'https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://georgiancollege.ca&strategy=mobile&key=APIKEY'
    var calls = [];
    calls.push(function(callback) 
      // First call
      https.get(builtWithCall, function(resource) 
        resource.setEncoding('utf8');
        resource.on('data', function(data) 
          // console.log('BuiltWith received', data);
        );
      );
    );
    calls.push(function(callback) 
      // second call
      https.get(pagespeedCall, function(resource) 
        resource.setEncoding('utf8');
        resource.on('data', function(data) 
          // console.log(data);
        );
      );
    );
   else 
    // Premium user - comparison report
    let websites = [];
  
  async.parallel(calls, function(err, results) 
    if(err)
      console.log(err);
    
    console.log('async callback ', results);
    res.render('/generated-report', 
      title: 'Report',
      data: ,
    );
  );
);

我正在尝试一次运行多个异步 API 调用。问题是,当我尝试像这样运行它们时

async.parallel(calls, function(err, results) 
  if(err)
    console.log(err);
  
  console.log('async callback ', results);
  res.render('/generated-report', 
    title: 'Report',
    data: ,
  );
);

控制台不记录任何内容。

当我在这里做控制台日志时

function(callback) 
  // second call
  https.get(pagespeedCall, function(resource) 
    resource.setEncoding('utf8');
    resource.on('data', function(data) 
      // console.log(data);
    );
  );

它记录响应。 pageSpeed 进入一个奇怪的循环并重复多次,但至少它有效。

现在我在 async.parallel 部分做错了什么?还有function(callback) 中的这个回调是什么?

编辑:

这是新版本的匿名函数:

function(callback) 
  // second call
  var results;
  https.get(pagespeedCall, function(resource) 
    resource.setEncoding('utf8');
    resource.on('data', function(data) 
      results += data;
      // console.log(data);
    );
    resource.on('end', function(data) 
      callback(null, data);
    );
    resource.on('error', function(err) 
      callback(err);
    );
  );

【问题讨论】:

【参考方案1】:

你需要调用传入的callback。查看您的一个并行函数,您没有调用callback()。我假设你的 resource 对象有一个 end & error

function(callback) 
  // second call
  var results;
  https.get(pagespeedCall, function(resource) 
    resource.setEncoding('utf8');
    resource.on('data', function(data) 
       results += data;
      // console.log(data);
    );
    resource.on('end' function() 
      callback(null, results);
    );
    resource.on('error' function(err) 
      callback(err);
    );
  );

async.parallel 的工作原理是所有调用的函数都必须依次调用传入的回调函数;在你的情况下是callback。 一旦并行中的每个函数都调用了回调,那么只有这样才会调用最终的函数,即您定义为function(err, results) ...的函数。

有一个警告,如果在 callback 调用中为第一个参数传递非空值,那么将立即调用最终函数,如果发生错误,您应该在其中处理该错误。

【讨论】:

我真的很困惑。现在 async.parallel 中的 console.log(results) 返回 2 undefined。至少正在拨打电话。知道问题是什么吗?我将编辑我的帖子以粘贴该函数的工作版本 你的意思是呼叫console.log('async callback ', results); 没有显示results 是的。我不知道为什么 这是因为您遇到错误并且该函数正在填充参数err,或者您没有将数据传递到results。使用回调中的第二个参数传递数据是您的工作。即callback(null, "Hello World"); 现在result 对象将包含["Hello World"] resource.on('end', function(data) callback(null, data); ); 到目前为止我有这个。这是错的吗?

以上是关于很难理解节点中的 async.parallel的主要内容,如果未能解决你的问题,请参考以下文章

我发现很难理解 C# 中的继承 [关闭]

如何在 plsql 的 varchar2 字段中的 xml 节点末尾插入“1”?

如何理解区块链技术

有关使用node-postgres和render page的节点js中的回调的问题

Prolog中的广度优先搜索

共识(Raft)算法详解