【问题标题】:When and how is this function being called in JavaScript?何时以及如何在 JavaScript 中调用此函数?
【发布时间】:2014-02-16 21:44:01
【问题描述】:

我正在通过this 教程使用 JavaScript 实现一个 Promise 库。我对 JavaScript 还很陌生,但我有广泛的 Java 背景。

我遇到了以下令我困惑的代码。

var maybeOneOneSecondLater = function() {
    var callback;
    setTimeout(function() {
        callback("hello, there");
    }, 1000);
    return {
        then: function(_callback) {
            callback = _callback;
        }
    };
};

考虑我拨打以下电话。

maybeOneOneSecondLater();

似乎应该调用 setTimeout。什么都没有发生,此时回调显然是未定义的。

但是当我拨打以下电话时:

maybeOneOneSecondLater().then(function(message){
     alert(message);
});

变量回调被赋值,setTimeout方法执行回调。我收到显示消息“你好,那里”的警报。

我真的不知道用 Google 来回答这个问题。在我看来,有些东西正在“监视”,因为没有更好的术语,回调变量,一旦分配它就会执行代码。

有人可以向我解释这里发生了什么吗?谢谢!

更新 我缺少的是调用 setTimeout 回调之前的一秒钟。谢谢大家的精彩回答。毕竟没有魔法。 :)

【问题讨论】:

    标签: javascript closures settimeout promise


    【解决方案1】:

    maybeOneOneSecondLater() 被调用时,它的var callback 被绑定到它出现在其主体中的两个地方:在传递给SetTimeout 的匿名函数中和在“非匿名函数”中,即@987654324 @ 它返回的对象的成员。这些绑定是“闭包”,在函数调用中仍然存在。

    这个:

    maybeOneOneSecondLater().then(function(message){
       alert(message);
    });
    

    等价于:

    var x = maybeOneOneSecondLater();
    var y = function(message){
       alert(message);
    };
    x.then(y);
    

    如果第一行和第二行由允许 1 秒超时启动的代码分隔,则 JavaScript 将留下未分配的 callback 变量,它不能将其解释为可以使用"hello world"参数。

    【讨论】:

      【解决方案2】:

      在函数中创建一个函数会创建一个闭包。内部函数继续可以访问外部变量。

      由于 setTimeout 在调用maybeOneOneSecondLater 时不会立即执行,因此then() 仍有时间在时间​​到期之前分配回调。

      【讨论】:

        【解决方案3】:

        没有什么在“观察”它,它的价值正在改变。来,试试这个:

        for( i=0; i<5; i++) setTimeout(function() {alert(i);},i*1000);
        

        您希望在单独的警报中得到 0,然后是 1、2、3 和 4,对吗?错误的。每个人都会收到 5 个警报。

        这是因为值发生了变化。

        【讨论】:

        • 而且因为内部函数仍然可以访问外部范围。
        【解决方案4】:

        没有人在看它。

        在调用maybeOneOneSecondLater() 1 秒后,调用传递给setTimeout 的函数(这就是setTimeout 所做的)。

        .then(function(message){alert(message);}); 运行并导致分配给callback 的时间不到 1 秒

        【讨论】:

          【解决方案5】:

          据我了解:

          maybeOneOneSecondLater 返回一个对象,该对象带有一个名为 then 的函数,该函数接受一个回调作为参数并将其分配给设置为在 1 秒后调用的变量 callback

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-11-10
            • 1970-01-01
            • 1970-01-01
            • 2017-03-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多