简体   繁体   English

在JavaScript中创建队列并在匿名函数中访问全局变量

[英]Creating a queue in JavaScript and access global variables in an anonymous function

I'm not well versed in JavaScript. 我不太精通JavaScript。 I have an object below (Foo.bar) that I want to both feed and print items from a queue every 100 ms. 我在(Foo.bar)下有一个对象,我想每100毫秒从队列中馈送和打印项目。

var Foo = Foo || {};
Foo.bar = {
    initialize: function () {
        this.feedQueue();
        this.consumeQueue();
    },
    queue: [],
    consumeQueue: function () {
        if (this.queue > 0) {
            var item = this.queue.shift();
            console.log(item);
        }
        setTimeout(function () {
            this.consumeQueue();
        }, 100);
    },
    feedQueue: function () {
        this.queue.push(Math.random());
        setTimeout(function () {
            this.feedQueue();
        }, 100);
    }
};
Foo.bar.initialize();

Within the consumeQueue function "this.queue" never updates. 在消耗队列函数中,“ this.queue”从不更新。 It always is empty. 它总是空的。

Can anyone help me out here with what I am doing wrong? 有人可以帮我解决我做错的事情吗?

You need to bind the scope to your timeout functions, otherwise this has a different context. 您需要范围绑定到超时功能,否则this具有不同的上下文。

setTimeout((function () {
    this.consumeQueue();
}).bind(this), 100);

Fiddle 小提琴

why bind, why argument? 为什么要绑定,为什么要争论?

setTimeout((function () {
    Foo.bar.consumeQueue();
}), 100);

In your callback function this is equal to window because this is omitted when calling the callback. 在回调函数this等于window ,因为this调用回调时被省略。

As RienNeVaPlus said in his answer you can use bind like this 正如RienNeVaPlus在他的回答中所说,您可以像这样使用bind

setTimeout((function () {
    this.consumeQueue();
}).bind(this), 100);

OR you can pass this as a parameter to your callack function 或者您可以this作为参数传递给callack函数

setTimeout(function (context) {
    context.consumeQueue();
}, 100, this);

In both case if you use IE as a browser, you will need IE9 at least. 在这两种情况下,如果将IE用作浏览器,则至少需要IE9。

As a final alternative to binding or passing it to the callback function, this should work pre IE9: 作为将其绑定或传递给回调函数的最终替代方法,这应在IE9之前运行:

...

consumeQueue: function () {

    if (this.queue > 0) {
        var item = this.queue.shift();
        console.log(item);
    }
    var that = this;
    setTimeout(function () {
        that.consumeQueue();
    }, 100);
},

...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM