У меня есть JS-программа, которая выполняет множество вызовов fetch() для определенного API. Я хочу абстрагировать все вызовы fetch() в один класс, называемый apiService, поэтому мой код будет более читабельным. Я хочу, чтобы apiService применял некоторый интеллект, а затем возвращал ответы вызывающему абоненту следующими способами: - apiService должен проверить ответ, чтобы увидеть, есть ли ошибки, которые он должен всегда обрабатывать одинаково. - fetch() иногда получает "res", который является необработанными данными и должен использоваться как есть, и иногда он получит json, который нуждается в.then(res => res.json(), затем (res применяется так, чтобы он может вернуть объект.
Поэтому я не могу просто выполнить "возврат fetch (..." из apiService, потому что apiService необходимо обработать один или несколько блоков.then() с ответом. Но мне также нужно вернуть что-то, что заставляет код вызова работать асинхронно, а не блокировать и ждать.
Кто-нибудь знает, как я мог бы структурировать функцию apiService для обработки html-ответов, но также возвращать асинхронно, то есть вызывающая функция получит объект результата после проверки ошибок и т.д.
Поэтому я не могу просто выполнить "возврат fetch (..." из 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')
})
return fetch(furl, options).then(res => res.json({ // a }).then(res => { // b; return res}));
В точках // a и // b я могу сделать любую промежуточную обработку, которая мне нужна
Существует хорошая статья об этом здесь, называемая "Синхронная" выборка с асинхронным/ожиданием, которая сломает ее для вас.
Вкратце:
Вы можете использовать await
при использовании fetch()
:
const response = await fetch('https://api.com/values/1');
const json = await response.json();
console.log(json);
Сначала мы ждем завершения запроса. Тогда мы можем дождаться завершения (или сбоя), а затем передать результат переменной json.
Полный пример - использовать async
, потому что "ожидание не будет работать без него:
const request = async () => {
const response = await fetch('https://api.com/values/1');
const json = await response.json();
console.log(json);
}
request();
Вы можете использовать библиотеку под названием 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*/});
Я думаю, вы можете выполнить свое требование, используя 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
res
- это не «необработанные данные», это объект ответа. И как вы хотите проверить ответ, как вы можете отличить JSON от чего-то еще?