【问题标题】:Assign Fetch JSON response to property in constructor [duplicate]将 Fetch JSON 响应分配给构造函数中的属性 [重复]
【发布时间】:2019-11-10 16:26:30
【问题描述】:

我有一个具有这种结构的类:

class MyClass{
    json;

    constructor(){

    }
}

我想将构造函数中的 API 请求中的“json”属性分配为数组。

我尝试了各种方法,甚至直接从其他论坛复制了代码 sn-ps。在调试器和console.log() 中,我已经确认我实际上得到了响应,并且在Promise.prototype.then() 中我能够使用结果。但我就是无法将它分配给类属性。

这些例子不起作用:

class MyClass{
    json;

    constructor(){
        fetch(url)
            .then(response => response.json())
                .then(json =>  {
                this.json = json;   // I've tried using "self" when not using the "=>" operator
            });
    }
}
class MyClass{
    json;

    constructor(){
        fetch(url)
            .then(response => response.json())
                .then(json =>  {
                this._setJson(json);
            });
    }

    _setJson(json){
        this.json = json;
    }
}

我也尝试过将json 初始化为一个数组并使用this.json.push(json) 或将json 作为一个对象返回。 一直以来this.json 从未被分配,我得到ReferenceError: json is not defined↵ at eval (...

我希望它被分配,但显然不是。 另外,如果这有什么不同,我正在使用 Chrome 75。 - 谢谢

【问题讨论】:

  • 您如何以及何时访问/使用json?考虑到该属性只有在请求完成后才会有值。
  • 该类的数据至关重要。我想稍后在构造函数以及其他方法中使用它。我尝试过使用 asyncawait 关键字,但我会首先承认我并不完全理解它们的含义。
  • 我建议你不要在类构造函数中执行异步任务。如果您要获取的数据对类至关重要,我会在类之外获取它,一旦数据可用,就创建一个类的实例,将数据传递给它。 asnycawait 使您的代码看起来是同步的并且更易于阅读,但代码仍然是异步的,因此您将面临同样的问题。
  • 谢谢,我看看结果如何。
  • 是的,我很确定这是同步问题。当我从控制台访问该对象的方法时 - 在一切都运行之后 - 我得到 json 填充。

标签: javascript json promise fetch


【解决方案1】:

你的结构看起来有点不对劲:

class MyClass{
    constructor() {
        this.json = null;

        //fetch logic here
    }

    _setJson(json){
        this.json = json
    }
}

【讨论】:

【解决方案2】:

执行回调时,this 指向全局范围而不是 MyClass 范围。要解决此问题,请将对象的上下文保存到某个变量中,例如 self:

class MyClass {
    json;

    getJson() {
        return this.json;
    }

    constructor(myCallback) {
        var self = this;
        fetch("https://www.mocky.io/v2/5185415ba171ea3a00704eed").then(function(response) {
            return response.json().then(function(json) {
                alert(this == myClassInstance); // false
                alert(self == myClassInstance); // true
                self.json = JSON.stringify(json);
                myCallback();
            });
        });
    }
}

var myCallBackImpl = () => { document.getElementById("response").innerHTML = myClassInstance.getJson(); }
var myClassInstance = new MyClass(myCallBackImpl);

【讨论】:

  • 正如我所说的“我在不使用“=>”运算符时尝试使用“self”。
  • 即使使用箭头功能也能正常工作。我已经在 Chrome 75.0.3770 上测试了这个 sn-p。
  • myCallback 是做什么的?因为如果我把它去掉,它的行为就像我的代码一样,而且我的代码没有这些回调的东西。谢谢
  • 回调只是一个例子,你可以把它从代码中拿出来,但要记住json会在`fetch`运行结束时得到一个值
  • 是的,我很确定这是同步问题。当我从控制台访问该对象的方法时 - 在所有内容运行后 - 我得到 json 填充。感谢您的所有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 2018-04-03
  • 2014-08-21
  • 2017-10-20
  • 2020-02-03
相关资源
最近更新 更多