如何处理fetch()响应并仍然异步工作

时间:2018-10-23 04:53:12

标签: javascript asynchronous promise es6-promise

我有一个JS程序,它对特定的API进行了大量的fetch()调用。我想将所有fetch()调用抽象为一个名为“ apiService”的类,这样我的代码将更具可读性。我希望apiService通过以下方式应用一些智能,然后将响应返回给调用方:  -apiService应该检查响应以查看是否存在错误,必须始终以相同的方式进行处理。  -fetch()有时会收到一个“ res”,它是原始数据,应按原样使用,有时它会收到需要一个.then(res => res.json()。then(res可以返回一个对象。

所以我不能仅仅从apiService中执行“ return fetch(...”),因为apiService需要处理一个或多个.then()响应块,但我还需要返回导致调用的内容代码以异步方式工作,而不会阻塞并等待。

任何人都知道如何构造apiService函数来处理html响应,但又异步返回,即调用函数将在错误检查等之后接收结果对象。

4 个答案:

答案 0 :(得分:2)

  

所以我不能仅仅从apiService中执行“ return fetch(...”),因为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')
})

答案 1 :(得分:0)

这里有一篇不错的文章,名为"Synchronous" fetch with 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();

答案 2 :(得分:0)

我认为您可以使用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

答案 3 :(得分:0)

您可以使用名为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*/});