Где разместить async / await в этом случае? - PullRequest
0 голосов
/ 14 июня 2019

Я просмотрел документы, прочитал другие вопросы и ответы, но все еще не могу понять, какую функцию сделать асинхронной и где разместить ожидание, чтобы получить желаемое поведение.

По сути, я хочу, чтобы console.log(this.data) в конструкторе выводил данные, которые я получаю, но сейчас он выдает ожидающие Promise.

Я попробовал буквально все, что могиз, я всегда заканчиваю выходом из системы либо Promise, либо undefined.

Где я могу добавить 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 нет проблем.Обещание (после разрешения) содержит реальный XMLHttpRequest с правильным ответом.

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

какую функцию сделать асинхронной

Простое правило: если функция содержит await, она должна быть помечена async.Он изменяет семантику функции так, что ее return фактически становится разрешением обещания и не будет иметь традиционного возвращаемого значения;в нем также говорится, что выполнение его частей (следующих за await) в конечном итоге будет в будущем, а не в рамках текущей задачи.

Однако вы не можете отложить создание объекта (когда конструктор возвращается, он должен вернуть созданный объект), поэтому конструктор не может быть async.

Вы все равно можете вывести this.data из кода, который находится внутри конструктора, но не во время выполнения конструктора.

Поскольку конструктор должен быть синхронным, чтобы построить объект, а запрос AJAX должен быть асинхронным (*), чтобы дать время ответа для поступления, яЯ сообщаю вам

Если я пойду на это совершенно неверно, тогда, пожалуйста, дайте мне знать.


*) Это вфакт не соответствует действительности;Вызов AJAX может быть синхронным (передавая false в качестве третьего параметра xhr.open), но это сильно не рекомендуется .

2 голосов
/ 14 июня 2019

Единственный способ сделать то, что вы хотите в своем коде в конструкторе, используя 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
}
...