@vsuhachev

Как обработать асинхроный вызов внутри Promise?

При использовании fetch для отработки http-статусов, отличных от 200 я создаю Promise. Я написал такой код и он вроде делает то что нужно, но очевидно, что вызов resp.json().then() отрабатывает параллельно с возвратом ошибки и могут возникнуть потенциальные проблемы. Как в данном случае написать корректный код который не вызовет проблем?

fetch(url, opts)
            .then((resp)=> new Promise((resolve, reject) => {
                if (resp.ok) {
                    resolve(resp)
                } else {
                    const error = new Error(resp.statusText);
                    error.status = resp.status;
                    resp.json().then(json => {error.data = json}); // Problem here
                    reject(error)
                }
            }))
            .then(...)
            .catch(...)
  • Вопрос задан
  • 239 просмотров
Решения вопроса 2
mannaro
@mannaro Куратор тега JavaScript
Умею профессионально гуглить
fetch(url, opts)
  .then((resp) => {
    if (!resp.ok) {
      resp = resp.json().then(json => {
        var error = new Error(resp.statusText);
        error.status = resp.status;
        error.data = json;

        throw error;
      })
    }

    return resp;
  })
  .then(resp => {
    // use resolve
  })
  .catch(err => {
    // cathc here
  })
Ответ написан
alexey-m-ukolov
@alexey-m-ukolov Куратор тега JavaScript
Создавать Promise здесь и не нужно, поскольку catch ловит и синхронные ошибки, а then могут принимать не только Promise, но вообще любое значение.
Я на coffee переписал и в своём стиле, но общий смысл должен быть понятен
fetch(url, opts)
.then(
	(resp) ->
		unless resp.ok
			error = new Error(resp.statusText)
			error.status = resp.status
			error.data = null

			throwError = -> throw error

			resp.json()
			.then(
				(json) ->
					error.data = json
			)
			.then(throwError)
			.catch(throwError)

		return resp
)
.then(...)
.catch(...)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@vsuhachev Автор вопроса
В итоге пришел к такому коду:

fetch(url, opts)
  .then((resp) => {
    if (resp.ok) return resp;

    return resp.json()
      .then(json => json)
      .catch(() => null)
      .then(errData => {
        const error = new Error(resp.statusText);
        error.status = resp.status;
        if (errData) error.data = errData
        throw error;
      })
  })
  .then(...)
  .catch(...)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы