Hi there! Just want some community feedback on my c-promise2 package that provides an extended promise class on top of the native. The library allows you to:
- cancel a promise chain (with rejection)
- use class decorators
- pause/resume your promises
- handle timeouts
- capture promise chain progress
- use internal/external AbortController for sending abort signals
- use data flow
Any thoughts, which may arise when you see a code like the following are welcome :)
It's a generic React component that uses CPromise decorators to manage the life cycle of the async code including nested JSON requests. For example, this easily lets you avoid warnings like Warning: Can’t perform a React state update on an unmounted component
when you unmount a component with running async tasks.
Demo1
import { async, listen, cancel, timeout } from "c-promise2"; import cpFetch from "cp-fetch"; export class TestComponent extends React.Component { state = { text: "" }; @timeout(5000) @listen @async *componentDidMount() { console.log("mounted"); const response = yield cpFetch(this.props.url); this.setState({ text: `json: ${yield response.text()}` }); } render() { return <div>{this.state.text}</div>; } @cancel() componentWillUnmount() { console.log("unmounted"); } }
export class TestComponent extends React.Component { state = { text: "", items: [], progress: 0 }; constructor(props) { super(props); this.onAbortClick = this.onAbortClick.bind(this); } @cancel(E_REASON_CANCELED) onAbortClick() {} @canceled(function (err) { console.warn(`Canceled: ${err}`); if (err.code !== E_REASON_DISPOSED) { this.setState({ text: err + "" }); } }) @progress(function (progress) { console.log(`Progress: ${progress}`); this.setState({ progress }); }) @innerWeight(3) @listen @async *componentDidMount() { console.log("mounted"); // concurrent requests with CPromise.all: const items = yield [ this.fetchJSON( "https://run.mocky.io/v3/7b038025-fc5f-4564-90eb-4373f0721822?mocky-delay=2s" ), this.fetchJSON2( "https://run.mocky.io/v3/00758c80-8001-4bcc-bf7d-082ac3e1092b?mocky-delay=4s" ) ]; yield CPromise.delay(500); // just simulate another aync task yield CPromise.delay(500); yield CPromise.delay(500).weight(0); this.setState({ text: `${items.length} requests completed`, items }); } @timeout(15000) @async *fetchJSON(url) { const response = yield cpFetch(url); // cancellable request return yield response.json(); } @timeout(15000) @async *fetchJSON2(url) { const response = yield cpAxios(url); return response.data; } render() { return ( <div> {this.state.text || ( <div> <ProgressBar animated now={this.state.progress * 100 + ""} /> <button type="button" className="btn btn-warning" onClick={this.onAbortClick} > Abort sequence </button> </div> )} <ul> {this.state.items.map((item, i) => ( <li key={i}>{JSON.stringify(item)}</li> ))} </ul> </div> ); } @cancel(E_REASON_DISPOSED) componentWillUnmount() { console.log("unmounted"); } }
Top comments (0)