【问题标题】:why it is possible to pass the undeclared function to setTimeout为什么可以将未声明的函数传递给 setTimeout
【发布时间】:2016-07-19 16:35:23
【问题描述】:

以下是 Trevor Burnham 的“Async JavaScript”一书(The Pragmatic Bookshelf,2012 年)中的代码示例:

var async = require ('async');

var start = new Date;

async.series([
  function(callback) { setTimeout(callback, 100); },
  function(callback) { setTimeout(callback, 300); },
  function(callback) { setTimeout(callback, 200); }
], function(err, results) {
  // show time elapsed since start
  console.log('Completed in ' + (new Date - start) + 'ms');
});

这让我很困惑,为什么可以使用 setTimeout 来安排未声明的“回调”函数?代码在节点中执行正常,但它到底做了什么? “回调”的调用是否真的被安排在指定的时间点执行,它们真的执行了吗?

【问题讨论】:

标签: javascript callback async.js


【解决方案1】:

callback 没有被声明,它作为参数传递给匿名函数,就在这里:

function(callback) { setTimeout(callback, 100); }
         ^^^^^^^^               ^^^^^^^^
            |                      |
            +----------------------+

它由实际执行匿名函数的人提供。 The documentation for async.series 说:

tasks - 包含要运行的函数的集合,每个函数都传递一个 callback(err, result) 它必须在完成时调用一个错误 err(可以是 null)和一个可选result 值。

【讨论】:

    【解决方案2】:

    是的 callback 已定义,但未在您的脚本中。在async模块的source代码中定义:

    'use strict';
    
    export default function(tasks) {
        function makeCallback(index) {
            function fn() {
                if (tasks.length) {
                    tasks[index].apply(null, arguments);
                }
                return fn.next();
            }
            fn.next = function() {
                return (index < tasks.length - 1) ? makeCallback(index + 1) : null;
            };
            return fn;
        }
        return makeCallback(0);
    }
    

    async 模块定义一个函数并将其作为callback 参数传递给串联的每个函数。

    【讨论】:

    • 我相信你的回答非常接近事实,但我没有看到 makeCallback() 返回的函数中解析的参数。根据文档,回调函数必须将其第一个参数(错误)传递给 async.series() 的“completionCallback”参数,或者传递给下一个任务执行。
    猜你喜欢
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2020-05-15
    • 2020-09-30
    • 1970-01-01
    相关资源
    最近更新 更多