Как обработать ответ fetch () и по-прежнему работать асинхронно - PullRequest
0 голосов
/ 23 октября 2018

У меня есть программа JS, которая выполняет множество вызовов fetch () для определенного API.Я хочу абстрагировать все вызовы fetch () в один класс с именем «apiService», чтобы мой код был более читабельным.Я хочу, чтобы apiService применил некоторый интеллект и затем возвратил ответы вызывающей стороне следующими способами: - apiService должен проверить ответ, чтобы увидеть, присутствуют ли ошибки, которые он всегда должен обрабатывать одинаково.- fetch () иногда получает «res», который является необработанными данными и должен использоваться как есть, а иногда он получает json, который нуждается в .then (res => res.json (). then (res применяется так, чтобы онможет вернуть объект.

Так что я не могу просто сделать «возврат извлечения (...» из apiService, потому что apiService нужно обработать один или несколько блоков .then () с ответом. Но я такженужно возвращать что-то, что заставляет вызывающий код работать асинхронно, а не блокировать и ждать.

Кто-нибудь знает, как я мог бы структурировать функцию apiService для обработки ответов html, но также возвращать асинхронно, т.е. вызывающая функция получит результатобъект после проверки ошибок и т. д.

Ответы [ 4 ]

0 голосов
/ 23 октября 2018

Так что я не могу просто сделать «возвратную выборку (...» из apiService, потому что apiService нужно обработать один или несколько блоков .then () с ответом. Но мне также нужно вернуть что-то, чтозаставляет вызывающий код работать асинхронно, а не блокировать и ждать.

Это дает мне ощущение, что вы, возможно, немного неправильно понимаете обещания. Возьмите этот пример:

const doAsyncWork = () => fetch('somewhere').then(() => console.log('fetch is complete'))
// use the above function
doAsyncWork().then(() => console.log('used the fetching function'))

Вывод приведенного выше кода будет

fetch is complete
used the fetching function

Как вы можете видеть, цепочкой then после вызова fetch вы фактически возвращаете результат then, а не извлекаете.Если подумать, что вы на самом деле возвращаете, если позвонили

const result = a().b().c() // we are really returning the result of `c()` here.

С учетом вышесказанного вы определенно можете сделать что-то вроде:

const apiCall = loc => fetch(loc).then(res => {
  // do things with your response

  return res
})

apiCall('someEndpoint').then(finalRes => {
  console.log('this is called after fetch completed and response processed')
})
0 голосов
/ 23 октября 2018

Я думаю, что вы можете выполнить свое требование, используя Promise.all()

Вот пример для вас.

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});

Для получения дополнительной информации вы можете обратиться:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

0 голосов
/ 23 октября 2018

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

Однако, если вы все еще хотите это сделать, используйте следующий способ.

вы можете использовать метод для создания таких обещаний.

 makeRequest(url, requestData) {

        const response = await fetch(url, requestData)
            .then(response => { console.info('network request successful to', url); return response.json() })
            .then(json => {
                console.info('response received for request', url, requestData, json)
                return json;
            })
            .catch(e => {
                console.error('error at request', url, requestData, e);
                return e
            });
        return response;
    }

и использовать такие обещания, как это

makeRequest('someurl', {
            method: 'GET'
        }).then(response=>{/*Your logic*/}).catch(error=>{/*Your logic*/});
0 голосов
/ 23 октября 2018

Здесь есть хорошая статья под названием "Синхронная" выборка с async / await , которая разбивает ее на вас по частям.

Короче :

Вы можете использовать await при использовании fetch():

const response = await fetch('https://api.com/values/1');
const json = await response.json();
console.log(json);

Сначала мы дождемся завершения запроса, Затем мы можем дождаться его завершения (или сбоя) и затем передать результат в переменную json.

Полный пример будет использовать async, потому что `await не будет работать без него:

const request = async () => {
    const response = await fetch('https://api.com/values/1');
    const json = await response.json();
    console.log(json);
}

request();
...