在这种情况下,应在哪里放置异步/等待?

时间:2019-06-14 03:53:20

标签: javascript promise async-await xmlhttprequest

我浏览了文档,阅读了其他问题和答案,但是我仍然不知道要使用什么函数来进行异步操作,以及在哪里放置等待项,以获得所需的行为。

基本上,我希望构造函数中的console.log(this.data)注销我提取的数据,但由于现在它注销了待处理的Promise

我已经尽力想尽一切办法,但我总是最终注销Promiseundefined

在哪里可以在这些方法中添加async / await以使其注销构造函数中提取的数据?

如果我以完全错误的方式进行操作,请告诉我。


class Apa {

  constructor () {

    this.ajaxURL = 'https://example.com/api/';
    this.mockParams = {
      title: 'foo',
      body: 'bar',
      userId: 1
    };

    this.data = this.getData(this.mockParams).then(xhr => this.data = JSON.parse(xhr.response)).catch(xhr => this.data = {});
    console.log(this.data);

  }

  getData(params) {

    return new Promise((resolve, reject) => {

      let request = this.postAjax(this.ajaxURL, params);
      request.then((xhr) => {
        resolve(xhr);
      }).catch((xhr) => {
        this.errorMessage = 'Ajax request failed: getData()';
        reject(xhr);
      });

    });

  }

  postAjax(url, data) {

     return new Promise((resolve, reject) => {
            var params = typeof data == 'string' ? data : Object.keys(data).map(
                function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }
            ).join('&');

            var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
            xhr.open('POST', url);
            xhr.onreadystatechange = function() {
                if (xhr.readyState>3 && xhr.status==200) { resolve(xhr); }
            };
            xhr.onerror = () => reject(xhr);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send(params);
        });

  }

}

注意: 我知道该类不能按原样工作,我不得不用模拟东西替换真实的API端点,但是我可以确保您在对真实API的调用中没有问题。 Promise(在解决时)确实包含带有正确响应的真实XMLHttpRequest。

2 个答案:

答案 0 :(得分:3)

  

进行异步的功能

简单规则:如果函数包含await,则必须将其标记为async。它改变了函数的语义,因此它的return实际上变成了Promise的解析,并且没有传统的返回值。它还说,它的某些部分(在await之后的部分)的执行将最终在将来,而不是在当前任务中执行。

但是,您不能延迟对象的创建(构造函数返回时,它必须返回构造的对象),因此构造函数不能为async

您仍然可以从构造函数内的代码中输出this.data,但在构造函数执行时则不能。

由于构造函数必须是同步的以便构造对象,而AJAX请求必须是异步(*)以便给出响应时间,所以我我让你知道

  

如果我以完全错误的方式进行操作,请告诉我。


*)实际上这是不正确的; AJAX调用 可以是同步的(通过将false作为xhr.open的第三个参数),但这是heavily discouraged

答案 1 :(得分:2)

使用async / await在构造函数中的代码中执行所需操作的唯一方法是这样

class Apa {

  constructor () {

    this.ajaxURL = 'https://example.com/api/';
    this.mockParams = {
      title: 'foo',
      body: 'bar',
      userId: 1
    };
     (async () => {
       this.data = this.getData(this.mockParams).then(xhr => this.data = JSON.parse(xhr.response)).catch(xhr => this.data = {});
       console.log(this.data);
    })();
  }
  ... etc
}