首页 > 解决方案 > .bind(this) 在 xhr addEventListener 中不起作用

问题描述

.bind(this)在 xhr 请求的响应中不起作用

我试图搬到.bind(this)几乎所有我能想到的地方,但它仍然不起作用

最终我只需要捕捉this.obj.id

upload(blob8) {
    var data = new FormData();
    data.append("file", blob8);

    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;

    xhr.open(
      "POST",
      "URL"
    );
    xhr.setRequestHeader("Authorization", `Bearer ${this.state.accessToken}`); //<--- IS WORKING
    // xhr.setRequestHeader("Content-Type", "application/octet-stream");

    xhr.send(data);

    xhr.addEventListener("readystatechange", function() {
      if (this.readyState === 4) {
        console.log(this.responseText);
        this.obj = JSON.parse(this.responseText);
        console.log(this.obj);
        console.log(this.obj.id);
        this.uploadMetaData(this.obj.id).bind(this);  // <------- NOT WORKING
      } else {
        console.log("there is an error here");
      }
    });
  }

标签: reactjsxmlhttprequest

解决方案


编辑:

我错过了回调引用两个不同的this上下文。解决此问题的两种可能方法:

upload() {
    var that = this;
    xhr.addEventListener("readystatechange", function() {
        that.uploadMetaData(this.obj.id); 
    });
}

或者

upload() {
    var boundUploadMetaData = this.uploadMetaData.bind(this);
    xhr.addEventListener("readystatechange", function() {
        boundUploadMetaData(this.obj.id); 
    });
}

两者都将调用uploadMetaDatawith upload()this同时允许回调仍然引用xhr对象的this.

或者,我认为您根本不需要引用该xhr对象this

xhr.addEventListener("readystatechange", function() {
    if (xhr.readyState === 4) {
        var res = JSON.parse(xhr.responseText);
        this.uploadMetaData(res.id);
    } else {
        console.log("there is an error here");
    }
}.bind(this));

原始答案

假设这不是 ES2015 类的方法(如果thisin 的引用upload()正确,听起来好像不是),回调 for"readystatechange"将需要绑定到外部方法的 ( upload()) this

您应该能够执行以下任一操作:

xhr.addEventListener("readystatechange", function() {
  // callback body   
}.bind(this));

或者,如果您能够使用 ES2015 语法,那么

xhr.addEventListener("readystatechange", () => {
  // callback body   
});

因为箭头函数表达式this通过它们的词法范围绑定。


推荐阅读