importCPromisefrom"c-promise2";functionfetchWithTimeout(url,{timeout,...fetchOptions}={}){returnnewCPromise((resolve,reject,{signal})=>{fetch(url,{...fetchOptions,signal}).then(resolve,reject)},timeout)}constpromise=fetchWithTimeout('http://localhost/',{timeout:5000}).then(response=>response.json()).then(data=>console.log(`Done: `,data),err=>console.log(`Error: `,err))setTimeout(()=>promise.cancel(),1000);// cancel the pending chain when you need// yes, the related network request will be canceled too// CPromise.race([// fetchWithTimeout(url1), fetchWithTimeout(url2), fetchWithTimeout(url3)// ]).then(console.log); // The other two slower network requests will be aborted as well
exportclassAsyncComponentextendsReact.Component{state={};asynccomponentDidMount(){console.log("mounted");this.controller=newCPromise.AbortController();try{awaitthis.myAsyncTask1();constresult=awaitthis.myAsyncTask2();this.setState({text:result});}catch(err){if(CPromise.isCanceledError(err)){console.log("tasks terminated");return;}throwerr;}}myAsyncTask1(){returnCPromise.from(function*(){yield...yield...}).listen(this.controller.signal);}myAsyncTask2(){returnnewCPromise((resolve,reject,{onCancel})=>{//code}).listen(this.controller.signal);}componentWillUnmount(){console.log("unmounted");this.controller.abort();// kill all tasks}}
Using 'c-promise2' package we can do the following trick:
(Live Demo - jsfiddle.net/DigitalBrain/c6njyrt9... )
Simple React Demo of using AbortController signal - codesandbox.io/s/react-fetch-class...
Simple React Demo using hooks - codesandbox.io/s/react-cpromise-fe...