了解此 MDN 示例的回调

Understanding callback on this MDN example

代码来自关于如何使用 Node.js 和 mongoose 的 MDN tutorial。这个想法是提出并行请求以获取不同模型中的文档数。我不明白传递给每个 async.parallel 的回调从哪里来,它在哪里定义以及它做了什么,对我来说它似乎是一个虚拟函数。你能帮我理解一下吗?这是代码:

var Book = require('../models/book');
var Author = require('../models/author');
var Genre = require('../models/genre');
var BookInstance = require('../models/bookinstance');

var async = require('async');

exports.index = function(req, res) {

    async.parallel({
        book_count: function(callback) {
            Book.countDocuments({}, callback); // Pass an empty object as match condition to find all documents of this collection
        },
        book_instance_count: function(callback) {
            BookInstance.countDocuments({}, callback);
        },
        book_instance_available_count: function(callback) {
            BookInstance.countDocuments({status:'Available'}, callback);
        },
        author_count: function(callback) {
            Author.countDocuments({}, callback);
        },
        genre_count: function(callback) {
            Genre.countDocuments({}, callback);
        }
    }, function(err, results) {
        res.render('index', { title: 'Local Library Home', error: err, data: results });
    });
};

回调由异步包传递。

解释:

由于异步并行函数采用异步任务的数组或对象(在您的示例中),并且这些异步任务需要一个回调,该回调将在其执行完成或出现错误时被调用。因此,并行函数提供了这些回调函数,并会在所有回调函数都被调用或出现错误时调用您的回调函数(作为并行函数调用的第二个参数提供)。

您可以从这里查看详细说明 - https://caolan.github.io/async/v3/docs.html#parallel

更新:

将并行视为包装函数,例如:

function parallel(tasks, userCallback) {
    let tasksDone = [];
    function callback(err, data){ // this is the callback function you're asking for
        if(err){
            userCallback(err); // calling callback in case of error
        }else {
            tasksDone.push(data);
            if(tasks.length === tasksDone.length){
                userCallback(null, tasksDone); // calling callback when all the tasks finished
            }
        }
    }

    tasks.forEach(task => {
        task(callback); // calling each task without waiting for previous one to finish 
    })
}

注意:这不是 async 的并行函数的正确实现,这只是一个例子来理解我们如何在内部使用回调函数以及它的用例是什么