【问题标题】:Understanding callback on this MDN example了解此 MDN 示例的回调
【发布时间】:2021-07-01 22:18:00
【问题描述】:

代码来自MDN tutorial,关于如何使用 Node.js 和 mongoose。这个想法是发出并行请求以获取不同模型中的文档数。我不明白传递给每个 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 });
    });
};

【问题讨论】:

    标签: node.js mongoose async.js


    【解决方案1】:

    回调由异步包传递。

    解释:

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

    您可以从这里查看详细说明 - 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的并行函数的正确实现,这只是一个例子来了解我们如何在内部使用回调函数以及它的用例是什么

    【讨论】:

    • 感谢您的帮助!那么,让我问一下,“回调”在哪里定义?除了让知道异步任务已经完成之外,它还有什么用处? “回调”的内部行为是否由 async 定义(因为我看不到错误处理逻辑,也看不到下一个,也看不到结果)?
    • 换句话说,谁将参数“回调”传递给每个任务,以及该参数是如何或在哪里定义的?
    • @Mariano 检查更新的答案,我添加了一个示例
    • 谢谢@Abhay!!不,它更清楚!我真的很感激!
    • 欢迎 :)。请接受这个答案,这样对其他人也有帮助。
    猜你喜欢
    • 2015-04-07
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多