我正在尝试为我的React项目制作一个通用的Fetch方法。计划是向我的提取方法传递一个url和一些配置数据(方法,标头等)。然后将较少的技术数据返回给我的调用方法。我想从api调用返回数据,而有效载荷就是json数据。
return fetch(URL, config)
.then((response) => {
console.log('Fetch - Got response: ', response);
return response;
})
.then((response) => {
console.log('Json: ', response.status);
const result = { data: response.json(), status: response.status };
return result;
})
.catch((e) => {
console.log(`An error has occured while calling the API. ${e}`);
reject(e);
});
这是我最初的尝试,但我不确定自己在做什么。
我的控制台日志记录了“响应”,其中包含来自API调用的响应:
body: (...)
bodyUsed: true
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:49487//api/xxx/yyy"
API调用完成,并且我的状态为200。
该行:
console.log('Json: ', response.status);
按预期返回200。
我以前一直在做
return response.json()
然后我的主班获得了薪水,但没有任何身份。我想做的是返回我的有效载荷以及状态。
所以我试图将其更改为此:
const result = { data: response.json(), status: response.status };
return result;
但是我的通话应用程序现在看到:
data: Promise {<resolved>: Array(9)}
status: 200
我希望获取数据:MyPayloadArray,状态:200
我认为我在这里误解了诺言。 (我对他们很环保)。
使用Fetch方法的数据访问器:
static GetAll() {
return new Promise((resolve, reject) => {
const request = {
method: 'GET',
URL: `${Server.ApiURL}/api/admin/clients`,
};
fetchData(request)
.then((result) => {
console.log('GetAll sees response as ', result);
resolve(result);
})
.catch((error) => {
reject(new Error(error));
});
});
}
我试图像这样调用数据访问器类:
componentDidMount() {
ClientDataAccessor.GetAll()
.then((response) => {
console.log('Got list!', response);
this.setState({ clients: response, isLoading: false });
})
.catch((error) => {
console.log('Got error on list screen', error);
});
}
如何仅获取状态,并将有效负载返回到DataAccesor类?我想我只是搞砸了Promises ...,但是不确定这里的最佳模式。
我要去UI类,onComponentDidMount-> DataAccessor.GetAll-> FetchData。我想我在某个地方滥用Promise。
答案 0 :(得分:2)
这里的问题是response.json()
返回了另一个承诺。您必须自己解决该诺言对象,然后返回您要寻找的对象。
return fetch(URL, config)
.then((response) => {
console.log('Fetch - Got response: ', response);
return response;
})
.then((response) =>
response.json()
.then( (data) => { data, status: response.status } )
)
.catch((e) => {
console.log(`An error has occured while calling the API. ${e}`);
reject(e);
});
非常丑...
为什么不将其移至异步/等待功能?目前所有浏览器都支持它...
async myFetch(URL, config) {
try {
const response = await fetch(URL, config);
console.log('Fetch - Got response:', response);
const data = await response.json();
console.log('Fetch - Got data:', data);
return { data, status: response.status }
}
catch (e) {
console.error(`An error has occured while calling the API. ${e}`);
throw e;
}
}
在两种情况下,请注意您的函数都会返回另一个promise。
答案 1 :(得分:1)
我认为您可以使用 Promise.resolve 来解决您的问题,链接保证以获得您的结果对象:
...
.then(response => {
var status = response.status;
return Promise.resolve(response.json())
.then(data => ({ data, status }))
})
Promise.resolve 可以将Promise作为参数,并返回将使链扁平化的promise,因此您可以获得json parse的值并使用它。
答案 2 :(得分:1)
您需要进一步解决res.json()
才能获取信息。您可以执行以下操作:
return fetch(URL, config)
.then((response) => {
console.log('Fetch - Got response: ', response);
return response;
})
.then(response =>
response.json().then(json => ({
status: response.status,
json
})
))
.then(({ status, json }) => {
console.log({ status, json });
return { data: json, status: status };
})
.catch((e) => {
console.log(`An error has occured while calling the API. ${e}`);
reject(e);
});
上面的简洁版本可以是:
return fetch(URL, config)
.then(response => response.json()
.then(json => ({ status: response.status, data: json }) )
)
注意:因为它是多余的,因此从reject(e)
内部删除了catch
。