svelte 退订实际上是如何工作的?

how does svelte unsubscribe actually work?

我可以订阅这样的商店:

count.subscribe(value => {
  count_value = value;
});

但是当我们要取消订阅时,我们会将之前的订阅代码放入一个新的变量中(成为一个函数表达式)并且运行只有在组件被销毁时才会这样做(onDestroy

const unsubscribe = count.subscribe(value => {
    count_value = value;
});

onDestroy(unsubscribe);

问题是,将之前的函数放入一个名为 unsubscribe 的新变量中如何?可以对商店执行退订功能。我的意思是我们甚至根本不更改取消订阅实现的订阅代码,我们所做的只是将它放入一个新变量中,使其成为一个函数表达式,并且只通过 onDestroy 调用它,那么它如何神奇地退订?它实际上是如何工作的?

but when we want to unsubscribe we will put the previous subscribe code into a new variable

这不是这里发生的事情。函数没有赋值给unsubscribe变量;它的 return 值是另一个函数。

想象一下 subscribe 是这样的:

const subscribe = (callback) => {
  callback('the stored value')

  const unsubscribe = () => {
    // do all the stuffs to unsubscribe here...
    console.log('Your are unsubscribed!')
  }

  return unsubscribe
}

let count_value

// unsubscribe is now the function returned in the subscribe function
const unsubscribe = subscribe(value => {
  count_value = value;
})

console.log(count_value)

// calling this function will log 'You are unsubscribed!' in the console
unsubscribe()

subscribe 不会 return 您作为参数传递的函数:它 return 是一个实现取消订阅行为的新函数。


如果您查看自定义 store contracts 的 Svelte 文档,这会更容易理解(强调 添加):

Store contract

store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }

You can create your own stores without relying on svelte/store, by implementing the store contract:

  1. A store must contain a .subscribe method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling .subscribe. All of a store's active subscription functions must later be synchronously called whenever the store's value changes.
  2. The .subscribe method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store.

如果您想进一步证明 subscribe 的 return 值与您传递给它的函数不同,只需提取 store.subscribe:

的类型
Type subscribe = (subscription: (value: any) => void) => (() => void)

subscription 参数 (value: any) => void 的签名与 return 值 () => void.

的签名不匹配

这里是商店合约的一个简单实现,展示了如何构建取消订阅功能。

class Store {
    constructor(init) {
        this.subscribers = {};
        this.value = init;
    }
    subscribe(callback) {
        callback(this.value);
        const id = Symbol()
        this.subscribers[id] = callback;

        return () => delete this.subscribers[id]
        //     ^^^ unsubscribe function here ^^^

    }
    set(value) {
        this.value = value;
        for (const id of Object.getOwnPropertySymbols(this.subscribers)) {
            this.subscribers[id](value)
        }
    }
}