.then () срабатывает до разрешения обещания - PullRequest
0 голосов
/ 30 мая 2018

В моем проекте vanilla js есть следующая цепочка обещаний:

API.POST({link to login endpoint}, "email=foo&pass=bar")
.then(() => User.initiate(API))
.then(() => console.log(User.name || 'wat'));

Объект API имеет методы POST и GET, которые выглядят одинаково, за исключением типа запроса:

GET (url, params = null) {
    console.log("GET start");
    return new Promise((resolve,reject) => {
        this._request('GET', url, params)
        .then(result => resolve(result));
    });
}

POST (url, params = null) {
    return new Promise((resolve,reject) => {
        this._request('POST', url, params)
        .then(result => resolve(result));
    });
}

... и метод _request, отвечающий за отправку запроса:

_request (type, url, params = null) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.responseType = 'json';
        xhr.open(type,url,true);
        xhr.withCredentials = true;
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        xhr.onload = function(){
            if (this.status == 200) {
                console.log(type + ' done');
                resolve(this.response);
            } else {
                reject(this.response._status.code);
            }
        };

        xhr.send(params);

    });
}

Объект пользователя приложения предоставляет метод "initiate", который вызывает API, чтобы проверить, вошел ли пользователь в систему. При положительном ответе API возвращает _embedded.user объект, который на следующем шаге используется для заполнения пользовательских свойств приложения:

initiate(API) {
    API.GET({link to authorization check endpoint})
    .then(authData => this.regenerate(authData._embedded.user));
},
regenerate(userData) {
    this.name = userData.name;

    // and so on, for each User property

    return new Promise((resolve,reject) => {
        resolve(this);
    });
}

Я ожидаю, что произойдет следующее:

  1. Отправлен запрос API для входа в систему(это просто для того, чтобы пропустить фактический процесс входа в систему, который не имеет отношения к текущей работе)
  2. API возвращает cookie, что позволяет проводить дальнейшее тестирование как зарегистрированный пользователь
  3. Отправляется запрос к API, чтобы спросить,аутентификация пользователя
  4. API отвечает подтверждением, а объект _embedded.user
  5. Свойства объекта приложения пользователя заполняются данными из ответа API
  6. User.nAme зарегистрирован в консоли

Шаг 6, хотя происходит между шагами 3. и 4., и я не могу найти причину.Моя консоль выглядит следующим образом (обратите внимание на console.logs в объектном коде API выше):

POST выполнено

GET start

wut

GETсделано

Что может быть причиной этого?Заранее спасибо.

1 Ответ

0 голосов
/ 30 мая 2018

Отсутствует return в initiate()

initiate(API) {
   return API.GET({link to authorization check endpoint})
   //^^ return the promise
    .then(authData => this.regenerate(authData._embedded.user));
}

Также используется анти-шаблон обещания в ваших методах GET и POST.Нет необходимости создавать новое обещание в каждом, поскольку _request() уже возвращает обещание

Все, что вам нужно:

GET (url, params = null) {
    return this._request('GET', url, params);
}

POST (url, params = null) {
    return this._request('POST', url, params);       
}

Для более подробного объяснения см. Что такоеявное обещание построения антипаттерна и как мне его избежать?


Вместо использования XMLHttpRequest вы также можете захотеть взглянуть на использование более поздних fetch() API, которыеимеет встроенные обещания и улучшенную обработку ошибок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...