【问题标题】:Calling a callback function from async.each and processing the results从 async.each 调用回调函数并处理结果
【发布时间】:2021-06-13 06:37:45
【问题描述】:

我刚刚开始使用 Javascript 和 Node,而异步和回调概念目前还不是我能控制的。

我必须为文档数组的每个元素调用一个函数。此函数将调用 DB 并为我获取文档注释数组。我想获取所有注释并将它们放在同一个数组上。类似的东西:

     //function in an async waterfall
      function(docs,callback){
        let annotationsArray = [];
        async.each(docs, (doc, callback2) => {
          getAnnotationsFromDocument(doc.Id, callback2);
        }, function (err,annotations){
          if (err){
            callback(err);
          } 
          annotationsArray = annotationsArray.concat(annotations);
          callback(null, annotationsArray);
        });
        
      },
//Next waterfall function

关于getAnnotationsFromDocument函数,这是它的简化结构:

function getAnnotationsFromDocument(docId,callback){
  
initDB();

  var async = require('async');
  async.waterfall([
    function authorize(callback){
      //checkAuthorization
(...)
    },
    function getRfpdocAnnotations(auth, metadata, callback){
      //call to DB
(...)
    },    
    function processRfpdocAnnotations(rfpDocAnnotations,metadata,callback){
 (...)
      callback(null,annotationsList);
    }
  ], function (err, result) {
    if(err) {
      callback(err);
    } else {
      callback(null, result);
    }       
  });   
}

很遗憾,我无法正确编码。在退出 async.each 之前,我无法从函数中获取结果。有人可以解释一下如何构造代码吗?

调试我发现函数 getAnnotationsFromDocument 获取数据并正确执行最后一个 callback(null, result); ,但是当我到达 function (err,annotations){ ,注释未定义。

【问题讨论】:

  • 您能告诉我们getAnnotationsFromDocument() 的代码吗?为什么它甚至不使用doc 参数?如果我们能看到该代码,我们可能会向您展示一个更好的方法。
  • 另外,为了正确使用async.each()(现在通常用基于promise的流控制来代替),你需要在你分配@之后将callback(null, annotationsArray)放在前面的回调中987654327@ 在同一个函数中。 async.each() 不会阻止。它在完成时调用它的回调,因此只有当async.each() 告诉你它完成时你才需要调用你的回调。这段带有 3 个回调的代码正是为什么应该将 async.each() 替换为基于 Promise 的控制流。
  • 谢谢@jfriend00。我更改了回调的位置,添加了您要求的功能,并使用更改的结果更新了问题。不幸的是,我仍然收到未定义的注释。
  • 如果您希望人们能够理解这里的整个问题并更有可能提供帮助,您将不得不展示所有相关代码,而不仅仅是代码大纲。问题很容易出现在这段代码中的任何地方,其中大部分你没有向我们展示。

标签: javascript node.js each async.js waterfall


【解决方案1】:

好的,我想我明白了:

  • 第一个问题是 async.each 没有像我预期的那样在回调中返回结果。与瀑布不同,它只返回错误。我应该更加注意阅读文档。
  • 其次,我必须在 getAnnotationsFromDocument 调用上创建一个回调来处理结果。
  • 最后,我没有执行对 async.each 回调的调用,所以执行没有到达 async.each 回调,也没有继续到下一个 async.waterfall 函数。

老实说,我不确定这是一个正确的答案,但它确实达到了我想要达到的效果。

  // function part of an async.waterfall
  function(docs,callback){
    let annotationsArray = [];
    async.each(docs, (doc,callback2) => {    
      getAnnotationsFromDocument(doc._id, function(err,result){
          if (err){
            callback2(err);
          }else{
            annotationsArray = annotationsArray.concat(result);
          }
          callback2();
        })
    }, (err) =>{
      if( err ) {
        callback(err);
      } else {
        callback(null,annotationsArray); //to the next waterfall function
      }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 2013-07-03
    • 2013-01-09
    相关资源
    最近更新 更多