何时以及如何在JavaScript中调用此函数?

时间:2014-01-25 23:03:15

标签: javascript closures settimeout promise

我正在学习使用JavaScript实现promise库的this教程。我是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会回答这个问题。在我看来,由于缺少一个更好的术语,回调变量,它正在“观察”,一旦被分配,它就会执行代码。

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

UPDATE 我缺少的是在调用setTimeout的回调之前的一秒钟失效。谢谢大家的答案。毕竟没有任何魔法。 :)

5 个答案:

答案 0 :(得分:2)

据我所知:

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

答案 1 :(得分:1)

什么都没有看。

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

.then(function(message){alert(message);});运行时间不到1秒,导致某些内容被分配到callback

答案 2 :(得分:0)

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

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

你会期望在单独的警报中获得0,然后是1,2,3和4,对吗?错误。你会得到5个警报。

这是因为价值已经改变。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

maybeOneOneSecondLater()被调用时,它的var callback被绑定到它身体中出现的2个位置:传递给SetTimeout的匿名函数和“不那么匿名的函数” “它返回的对象的then成员。这些绑定是“闭包”,它在函数调用中幸存下来。

此:

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

相当于:

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

如果第一行和第二行被代码隔开,这将允许1秒超时进入,JavaScript将留下未分配的callback变量,它不能解释为可以调用的函数使用"hello world"参数。