Last active
April 21, 2022 18:15
-
-
Save maxfierke/5fb3708e4a41bc2a71700184915cbed9 to your computer and use it in GitHub Desktop.
cancelableFetch Yieldable ember-concurrency
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Yieldable } from 'ember-concurrency'; | |
import fetch from 'fetch'; // i.e. ember-fetch. could also use native fetch too. | |
class FetchYieldable extends Yieldable { | |
constructor(url, opts = {}) { | |
super(...arguments); | |
this.url = url; | |
this.opts = opts; | |
} | |
onYield(state) { | |
const controller = new AbortController(); | |
const { signal } = controller; | |
let isComplete = false; | |
fetch(this.url, { ...this.opts, signal }) | |
// eslint-disable-next-line promise/always-return | |
.then((response) => { | |
state.next(response); | |
isComplete = true; | |
}) | |
.catch((err) => { | |
if (err instanceof DOMException && err.name === 'AbortError') { | |
return; | |
} | |
state.throw(err); | |
}); | |
return () => { | |
if (!isComplete) { | |
// Aborting an already completed request with an as-yet unresolved Promise | |
// can cause an AbortError to be thrown which might get caught before | |
// the promise is resolved, so we should avoid that and never abort a | |
// request that we know has been completed. | |
controller.abort(); | |
} | |
}; | |
} | |
} | |
const cancelableFetch = (url, opts = {}) => new FetchYieldable(url, opts); | |
export default cancelableFetch; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cancelableFetch from './cancelable-fetch'; | |
class MyComponent extends Component { | |
@task({ drop: true }) | |
*getSomething() { | |
const response = yield cancelableFetch("https://example.com", { Accept: "application/json" }); | |
const json = yield response.json(); | |
return json; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment