如何在对象构造期间使用异步生成的值分配属性

How can a property be assigned during object construction with a value generated asynchronously?

本文关键字:异步 属性 分配 对象      更新时间:2023-09-26

如何在对象构造期间使用异步生成的值分配属性?

我正在尝试在构造过程中为需要通过 AJAX 检索的对象分配一个属性:

//define module prototype
Library.Module = function () {
    this.resources = {};
    for (var i = 0; i < arguments.length; i++) {
        // assume that Library.require makes a request and 
        // then executes this callback
        Library.require(arguments[i], function (resource) {
            // ! the problem seems to be that 'this' is undefined 
            // in the scope of the callback
            this.resources[resource.location] = resource;
        });
    }
};

我认为这段代码的意图相当明确 - 问题是this似乎在回调函数的范围内未定义。

如以下文章 https://blog.engineyard.com/2015/mastering-this-in-javascript 和评论中的讨论所示,一种可能的解决方案是将其存储在范围更高的变量中,以便在回调中使用它。

因此,可能的解决方案可能是:

Library.Module = function () {
    var _this = this;
    _this.resources = {};
    for (var i = 0; i < arguments.length; i++) {
      // assume that Library.require makes a request and 
      // then executes this callback
      Library.require(arguments[i], function (resource) {
        _this.resources[resource.location] = resource;
      });
   }
};

引用文章中的有用片段:

在回调中管理它

就是这样:这是设置函数此值的四种方法。 这四条规则并不难记住,但有一个共同点 你应该知道的陷阱。我说的是回调。这很容易 编写回调甚至不知道它,就像在 setTimeout 中一样:

setTimeout(function() {
    $(‘button’).addClass(‘red’);
}, 1000);

setTimeout 函数接受回调,但由于它没有使用 设置上下文的四个规则之一,默认为全局 窗口对象。在上面的例子中这很好,但变成了一个错误 像这样的代码:

$('button').on('click', function() {
    setTimeout(function() {
        // Uh oh! `this` is the global object!
        $(this).addClass('clicked');
    }, 1000); 
});

我们希望 $(this) 引用单击的按钮,但是 它不会,因为这默认为全局窗口对象。单程 解决这个问题是将我们期望的值存储在本地 变量,然后在子作用域中简单地使用该变量:

$('button').on('click', function() {
    var _this = this;
    setTimeout(function() {
        $(_this).addClass('clicked'); // All better
    }, 1000); 
});

当然,有很多方法可以完成同样的事情。你可以 使用 .bind()、.call() 或许多其他选项。选择有效的方法 最适合每种情况。