【问题标题】:Cache result from async function, and pass it to next function in Async.js缓存异步函数的结果,并将其传递给 Async.js 中的下一个函数
【发布时间】:2016-05-23 19:31:00
【问题描述】:

过去几天我一直在努力完成追随,但我无法解决。我觉得我什么都试过了。所以这里...

我的路线有一个 JSON 对象,其中包含创建新测验的所有信息。 换句话说 - 一个包含有关新测验的信息的对象,一个问题数组,其中每个问题都包含一个答案数组。

我使用 async.js 瀑布函数,并且想做以下事情:

  • 将新测验保存到数据库,并将从数据库返回的新测验 ID 传递给下一个瀑布函数

  • 遍历每个问题。缓存从数据库返回的新问题 ID,并将它们传递给下一个瀑布函数。这里的问题是缓存 ID。由于该函数是异步的,因此我无法将结果缓存到任何地方以用于下一个函数...

  • 遍历每个答案,并将它们保存到 DB

这就是我所拥有的:

router.post('/quiz/create', function (req, res) {
    // JSON object with the new Quiz
    var json = req.body;
    async.waterfall([
        function(callback) {
            // Returns a Quiz ID for the new quiz, and passes it to the next waterfall function
            db.createQuiz(json, function(err, result) {
                // ID returned from DB is formatted as [{'': id}], hence result[0]['']
                callback(null, result[0]['']);
            });
        },
        function(quizID, callback) {
            // Loop through each question in the quiz
            async.forEachSeries(json.questions, function(question, callback) {
               // Save the question to DB, and get the new question ID returned
               db.createQuestion(question, quizID, function(err, result) {
                   // TODO: cache the new question ID's in an array somewhere to be passed to the next waterfall function
                   // Start next iteration of the loop
                   callback();
               });
            }, function(err) {
                // Done with all questions. Pass question ID's to next function
                callback(null, cachedQuestionIDs);
            });
        },
        function(cachedQuestionIDs, callback) {
            // TODO: access the question ID's, and use them to loop through and save answers to DB
        }
    ], function(err, result) {
        res.json({
           success: true,
           message: 'Quiz created!'
       });
    });
});

【问题讨论】:

    标签: javascript node.js asynchronous async.js


    【解决方案1】:

    只需将值存储在async.forEachSeries() 之外的数组中,但在async.waterfall() 控制流中的包装第二个函数中。然后,您可以在您的 async.forEachSeries() 执行完毕后返回此数组。

    function(quizID, callback) {
      var cachedQuestionIDs = [];
    
      // Loop through each question in the quiz
      async.forEachSeries(json.questions, function(question, callback) {
        // Save the question to DB, and get the new question ID returned
        db.createQuestion(question, quizID, function(err, result) {
          // Store our result
          cachedQuestionIDs.push(result);
    
          // Start next iteration of the loop
          return callback();
        });
      }, function(err) {
        // Done with all questions. Pass question ID's to next function
        return callback(null, cachedQuestionIDs);
      });
    }
    

    【讨论】:

    • 谢谢 :) 这很奇怪,因为我之前一直尝试将 ID 添加到另一个范围内的数组中,它始终是 undefined。我现在可以在瀑布中的最后一个函数中访问 ID。明天我会努力让剩下的工作。我不禁觉得我的方法有点脏。在第二个瀑布函数中嵌套循环会更正确。对于我添加到数据库中的每个问题,我都可以遍历所有答案,并将它们循环到同一函数中的数据库中。但我不知道如何处理所有异步的事情。
    【解决方案2】:

    我终于让它正常工作,使用嵌套 forEachSeries 循环的问题和答案更优雅的解决方案。这里没有错误处理。只是为了展示基本思想。这是瀑布中的第二个函数。

    function(quizID, callback) {
    
            async.forEachSeries(json.questions, function(question, callback) {
                db.registerQuestion(question, quizID, function(err, result) {
                    async.forEachSeries(question.answers, function(answer, callback) {
                       db.registerAnswer(answer, result[0][''], callback); 
                    }, function() {
                        callback();
                    });
                });
            }, function() {
                callback();
            });
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-02
      • 2015-12-01
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 2021-12-27
      相关资源
      最近更新 更多