Merge pull request #2730 from sveltejs/gh-2553

allow derivers to return cleanup functions
pull/2744/head
Rich Harris 5 years ago committed by GitHub
commit 644b8a732d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -324,13 +324,13 @@ const time = readable(new Date(), set => {
store = derived(a, callback: (a: any) => any)
```
```js
store = derived(a, callback: (a: any, set: (value: any) => void) => void, initial_value: any)
store = derived(a, callback: (a: any, set: (value: any) => void) => void | () => void, initial_value: any)
```
```js
store = derived([a, ...b], callback: ([a: any, ...b: any[]]) => any)
```
```js
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void, initial_value: any)
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void | () => void, initial_value: any)
```
---
@ -359,6 +359,20 @@ const delayed = derived(a, ($a, set) => {
}, 'one moment...');
```
If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes:
```js
import { derived } from 'svelte/store';
const tick = derived(frequency, ($frequency, set) => {
const interval = setInterval(() => set(Date.now()), 1000 / frequency);
return () => {
clearInterval(interval);
}
}, 'one moment...');
```
---
In both cases, an array of arguments can be passed as the first argument instead of a single store.

@ -51,11 +51,14 @@ export function derived(stores, fn, initial_value) {
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) return;
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) set(result);
else cleanup = result || noop;
};
const unsubscribers = stores.map((store, i) => store.subscribe(
@ -74,6 +77,7 @@ export function derived(stores, fn, initial_value) {
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}

@ -211,6 +211,37 @@ describe('store', () => {
unsubscribe();
});
it('calls a cleanup function', () => {
const num = writable(1);
const values = [];
const cleaned_up = [];
const d = derived(num, ($num, set) => {
set($num * 2);
return function cleanup() {
cleaned_up.push($num);
};
});
num.set(2);
const unsubscribe = d.subscribe(value => {
values.push(value);
});
num.set(3);
num.set(4);
assert.deepEqual(values, [4, 6, 8]);
assert.deepEqual(cleaned_up, [2, 3]);
unsubscribe();
assert.deepEqual(cleaned_up, [2, 3, 4]);
});
});
describe('get', () => {

Loading…
Cancel
Save