缓存来自异步函数的结果,并将其传递给异步.js中的下一个函数

Cache result from async function, and pass it to next function in Async.js

本文关键字:异步 函数 js 下一个 结果 缓存      更新时间:2023-09-26

在过去的几天里,我一直在努力完成关注,但我无法解决它。我觉得我已经尝试了一切。所以在这里...

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

我使用 async.js 瀑布函数,并希望执行以下操作:

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

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

  • 循环浏览每个答案,并将它们保存到数据库中

这就是我得到的:

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!'
       });
    });
});

只需将值存储在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);
  });
}

我终于让它正常工作,使用嵌套的 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();
        });
}