使用 Axios 和 Promises 循环 API 调用
Looping API calls with Axios and Promises
我正在使用 Axios 进行 API 调用,对于一个调用,我想继续轮询 API 直到我得到响应。
但是,当我调用此函数时,某些东西比预期更早地解决了承诺。
我在这里调用函数:
componentDidMount() {
api.getUser(this.props.user.id)
.then((response) => {
console.log(response);
this.handleSuccess(response.content);
})
.catch((error) => {
this.handleError(error);
});
}
第 4 行的 console.log
显示 undefined
。该函数会继续轮询并在收到有效数据时停止。
函数本身:
getUser(id, retries = 0) {
return axios(getRequestConfig)
.then((res) => {
if (res.data && res.data.content.status === 200) {
return Promise.resolve(res.data); // success!
} else if (retries >= 15) {
return Promise.reject(res); // failure
} else {
// try again after delay
delay(1000)
.then(() => {
return this.getUser(id, retries + 1);
})
}
})
.catch(err => err);
}
我会将轮询逻辑外包到一个单独的函数中:
//expects fn() to throw if it failed
//if it runs out of retries, poll() will resolve to an rejected promise, containing the latest error
function poll(fn, retries = Infinity, timeoutBetweenAttempts = 1000){
return Promise.resolve()
.then( fn )
.catch(function retry(err){
if(retries-- > 0)
return delay( timeoutBetweenAttempts )
.then( fn )
.catch( retry );
throw err;
});
}
getUser(id) {
function validate(res){
if(!res.data || res.data.content.status !== 200)
throw res;
}
return poll(() => axios(getRequestConfig).then(validate), 15, 1000);
}
有一个库 axios-request-handler 支持开箱即用的轮询。
我正在使用 Axios 进行 API 调用,对于一个调用,我想继续轮询 API 直到我得到响应。
但是,当我调用此函数时,某些东西比预期更早地解决了承诺。
我在这里调用函数:
componentDidMount() {
api.getUser(this.props.user.id)
.then((response) => {
console.log(response);
this.handleSuccess(response.content);
})
.catch((error) => {
this.handleError(error);
});
}
第 4 行的 console.log
显示 undefined
。该函数会继续轮询并在收到有效数据时停止。
函数本身:
getUser(id, retries = 0) {
return axios(getRequestConfig)
.then((res) => {
if (res.data && res.data.content.status === 200) {
return Promise.resolve(res.data); // success!
} else if (retries >= 15) {
return Promise.reject(res); // failure
} else {
// try again after delay
delay(1000)
.then(() => {
return this.getUser(id, retries + 1);
})
}
})
.catch(err => err);
}
我会将轮询逻辑外包到一个单独的函数中:
//expects fn() to throw if it failed
//if it runs out of retries, poll() will resolve to an rejected promise, containing the latest error
function poll(fn, retries = Infinity, timeoutBetweenAttempts = 1000){
return Promise.resolve()
.then( fn )
.catch(function retry(err){
if(retries-- > 0)
return delay( timeoutBetweenAttempts )
.then( fn )
.catch( retry );
throw err;
});
}
getUser(id) {
function validate(res){
if(!res.data || res.data.content.status !== 200)
throw res;
}
return poll(() => axios(getRequestConfig).then(validate), 15, 1000);
}
有一个库 axios-request-handler 支持开箱即用的轮询。