如何在添加间隔时使用提取请求中的超时停止轮询
How to stop polling using timeout in fetch request while adding intervals
我正在轮询我的报告,在每个请求之间添加 5 秒的间隔。
const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST
})
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`
}
})
const resBody = await response.json()
if (resBody.status === 'success') {
window.location.href = resBody.url
dispatch({
type: constants.DOWNLOAD_REPORT_SUCCESS
})
} else {
await addDelay(5000)
await subscribe(url)
// return;
// setTimeout(() => {
// dispatch({
// type: constants.SHOW_DOWNLOAD_POPUP
// })
// return;
// }, 15000);
}
}
subscribe(url)
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status
})
}
}
现在,我想在 15 秒后停止轮询并显示一个弹出窗口。
问题是我无法在此处添加 setTimeout,因为我正在使用 async
。而且它不会一次又一次地停止调用 subscribe
方法,因为它不断进入 else 部分,return
不工作。
我想退出 else 部分,停止调用该函数并在 15 秒后显示弹出窗口。我该如何实现?
您的 return 语句不可能工作,因为此函数是 recursive - 如果获取一直失败,它永远不会到达那里。只添加一个索引来跟踪您重试订阅的次数怎么样?
const addDelay = (timeout) =>
new Promise((resolve) => setTimeout(resolve, timeout));
const failed = 0;
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST,
});
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`;
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`,
},
});
const resBody = await response.json();
if (resBody.status === 'success') {
window.location.href = resBody.url;
dispatch({ type: constants.DOWNLOAD_REPORT_SUCCESS });
} else {
if (failed >= 3) {
// whatever you want to do on fail
} else {
failed += 1;
await addDelay(5000);
await subscribe(url);
}
}
};
subscribe(url);
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status,
});
}
};
您可以跟踪自轮询开始以来经过的时间量,并在它达到零时退出。
const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST
})
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`
let remainingPollingTime = 15000 // <--------
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`
}
})
const resBody = await response.json()
if (resBody.status === 'success') {
window.location.href = resBody.url
dispatch({
type: constants.DOWNLOAD_REPORT_SUCCESS
})
} else {
if(remainingPollingTime <= 0) { // <--------
dispatch({
type: constants.SHOW_DOWNLOAD_POPUP
})
return
}
remainingPollingTime -= 5000 // <--------
await addDelay(5000)
await subscribe(url)
}
}
subscribe(url)
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status
})
}
}
我正在轮询我的报告,在每个请求之间添加 5 秒的间隔。
const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST
})
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`
}
})
const resBody = await response.json()
if (resBody.status === 'success') {
window.location.href = resBody.url
dispatch({
type: constants.DOWNLOAD_REPORT_SUCCESS
})
} else {
await addDelay(5000)
await subscribe(url)
// return;
// setTimeout(() => {
// dispatch({
// type: constants.SHOW_DOWNLOAD_POPUP
// })
// return;
// }, 15000);
}
}
subscribe(url)
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status
})
}
}
现在,我想在 15 秒后停止轮询并显示一个弹出窗口。
问题是我无法在此处添加 setTimeout,因为我正在使用 async
。而且它不会一次又一次地停止调用 subscribe
方法,因为它不断进入 else 部分,return
不工作。
我想退出 else 部分,停止调用该函数并在 15 秒后显示弹出窗口。我该如何实现?
您的 return 语句不可能工作,因为此函数是 recursive - 如果获取一直失败,它永远不会到达那里。只添加一个索引来跟踪您重试订阅的次数怎么样?
const addDelay = (timeout) =>
new Promise((resolve) => setTimeout(resolve, timeout));
const failed = 0;
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST,
});
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`;
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`,
},
});
const resBody = await response.json();
if (resBody.status === 'success') {
window.location.href = resBody.url;
dispatch({ type: constants.DOWNLOAD_REPORT_SUCCESS });
} else {
if (failed >= 3) {
// whatever you want to do on fail
} else {
failed += 1;
await addDelay(5000);
await subscribe(url);
}
}
};
subscribe(url);
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status,
});
}
};
您可以跟踪自轮询开始以来经过的时间量,并在它达到零时退出。
const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
export const myReport = () => async (dispatch) => {
dispatch({
type: constants.DOWNLOAD_REPORT_REQUEST
})
let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`
let remainingPollingTime = 15000 // <--------
try {
const subscribe = async (uri) => {
let response = await fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-api-token': `Bearer ${token}`
}
})
const resBody = await response.json()
if (resBody.status === 'success') {
window.location.href = resBody.url
dispatch({
type: constants.DOWNLOAD_REPORT_SUCCESS
})
} else {
if(remainingPollingTime <= 0) { // <--------
dispatch({
type: constants.SHOW_DOWNLOAD_POPUP
})
return
}
remainingPollingTime -= 5000 // <--------
await addDelay(5000)
await subscribe(url)
}
}
subscribe(url)
} catch (error) {
dispatch({
type: constants.DOWNLOAD_REPORT_FAILURE,
errorMessage: error.status
})
}
}