function sleep(t) {
return new Promise((resolve, reject) =>{
setTimeout(() => {
console.log('timeout!')
return resolve({isTimeout: true})
}, t);
});
}
function thirdPartyFunction(t) { // thirdPartyFunction can't be edited
return new Promise((resolve, reject) =>{
setTimeout(() => {
console.log('thirdPartyFunction completed!')
return resolve({success: true})
}, t);
});
}
function main() {
return new Promise(async(resolve, reject) => {
try {
let thirdPartyFunctionExecutionTime = Math.floor(Math.random() * 10) + 1;
thirdPartyFunction(thirdPartyFunctionExecutionTime * 1000, false).then( (r) => {
console.log('should not execute this if thirdPartyFunctionExecutionTime > timeout') // only goal
// other code which is not useful after timeout
});
const timeout = 3;
console.log(`thirdPartyFunctionExecutionTime: ${thirdPartyFunctionExecutionTime}, timeout - ${timeout}`)
await sleep(timeout * 1000, true);
throw 'stop main()'
// return
} catch (error) {
console.log('in catch')
return;
}
})
}
main()
Timeout is fixed. thirdPartyFunctionExecutionTime might be very large (sometimes) in my actual case, say 30 secs. I don't want something to be running on background after timeout.
thirdPartyFunction promise function should stop execution on timeout.
FYI, here's a generic function to add a timeout with the option of cancelling. This can be used with any promise to add a timeout to it.
If the underlying asynchronous operation represented by the promise is cancellable, then you can supply a cancel function. If the async operation finishes first, this will clean up the timer for you automatically so it doesn't keep running.
// the main purpose of this class is so that callers can test
// to see if the reject reason is a TimeoutError vs. some other type of error
class TimeoutError extends Error {
constructor(...args) {
super(...args);
}
}
// add a timeout to any promise
function addTimeout(promise, t, timeoutMsg = "timeout") {
let timer;
const timerPromise = new Promise((resolve, reject) => {
timer = setTimeout(() => {
timer = null;
// if the promise has a .cancel() method, then call it
if (typeof promise.cancel === "function") {
try {
promise.cancel();
} catch(e) {
console.log(e);
}
}
reject(new TimeoutError(timeoutMsg));
}, t)
});
// make sure the timer doesn't keep running if the promise finished first
promise.finally(() => {
if (timer) {
clearTimeout(timer);
}
})
return Promise.race([promise, timerPromise]);
}
And, you could then use this in your code like this:
function main() {
addTimeout(thirdPartyFunction(...), 3000).then(result => {
// thirdPartyFunction succeeded and timeout was not hit
// use the result here
}).catch(err => {
console.log(err);
// an error occurred here
if (err instanceof TimeoutError) {
// timeout
} else {
// other error
}
})
}
If your asynchronous operation has an ability to be cancelled if this operation times out, you could support that like this:
function main() {
let p = thirdPartyFunction(...);
p.cancel = function () {
// cancel the thirdPartyFunction here (depends uponn the specific operation)
}
addTimeout(p, 3000).then(result => {
// thirdPartyFunction succeeded and timeout was not hit
// use the result here
}).catch(err => {
console.log(err);
// an error occurred here
if (err instanceof TimeoutError) {
// timeout
} else {
// other error
}
})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.