Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we remove tap from hook? #109

Closed
wangzongxu opened this issue Sep 12, 2019 · 12 comments
Closed

Can we remove tap from hook? #109

wangzongxu opened this issue Sep 12, 2019 · 12 comments

Comments

@wangzongxu
Copy link

var hook = new SyncHook(['param'])
var fn = param => console.log(param)

hook.tap('example', fn)
hook.call('frist')
// frist

setTimeout(() => {
   hook.remove(fn)
}, 3000)
@alexander-akait
Copy link
Member

Why? I can't undestand, also it is internal module for webpack, what is use case using this without webpack?

@wangzongxu
Copy link
Author

Why? I can't undestand, also it is internal module for webpack, what is use case using this without webpack?

Because I using it in my Vue Component,
When I need to notify multiple components,
I need to add a tap when each component is mounted,
and need to remove a tap when each component is destroyed,

But I can't find anything as good as tapable for handling the flow of events.

I wanted to submit PR, but the 'lib/ hookcodefactory.js' file seemed too hard to understand.

@montogeek
Copy link
Member

How are you using this with Vue components?

@wangzongxu
Copy link
Author

How are you using this with Vue components?

const hook = new SyncHook()

// After a while
hook.call()

// dialog-a.vue
export default {
  methdos: {
     someMethod(){}
  }
  created() {
    hook.tap('If the dialog appears', this.someMethod)
  }
  destroyed() {
      // I want to remove it...
  }
}

@mengjian-github
Copy link

#71 (comment)

@wangzongxu

@sokra
Copy link
Member

sokra commented Sep 27, 2019

Due to internal optimizations done which depends on the taps called, it would be very inefficient to remove plugins. Therefore it it's not in the API. Avoid removing plugins.

Note that tapable is optimized for a call flow like: 1. attach to hooks, 2. call hooks at lot.
It's not an general purpose event emitter.

You could still handle your use case this way:

const hook = new SyncHook()

// After a while
hook.call()

const hookMethods = new Set();
hook.tap("dialog-a", () => { for(const m of hookMethods) m(); });

// dialog-a.vue
export default {
  methdos: {
     someMethod(){}
  }
  created() {
    hookMethods.add(this.someMethod);
  }
  destroyed() {
    hookMethods.delete(this.someMethod);
  }
}

but other solutions might be better for this

@Hypercubed
Copy link

@sokra Actually this is a real shame. tapable has a great API that's useful outside webpack. Lacking the ability to remove a tap really diminishes it's value.

@dabanlee
Copy link

dabanlee commented Jan 6, 2021

why don't you use event hub?

const eventHub = new Vue()

export default {
    created() {
        eventHub.$on('some-action', this.addTodo)
    },
    destroyed() {
        eventHub.$off('some-action', this.addTodo)
    },
    methods: {
        addTodo() {},
    },
}

@wangzongxu
Copy link
Author

why don't you use event hub?

const eventHub = new Vue()

export default {
    created() {
        eventHub.$on('some-action', this.addTodo)
    },
    destroyed() {
        eventHub.$off('some-action', this.addTodo)
    },
    methods: {
        addTodo() {},
    },
}

因为当应用变得复杂的时候,tapable覆盖的场景更全面

@keifergu
Copy link

need this feature

@keifergu
Copy link

keifergu commented Feb 1, 2021

@wangzongxu I find a method to remove tap:

var hook = new SyncHook(['param'])
var fn = param => console.log(param)

hook.tap('example', fn)
hook.call('frist')
// frist

setTimeout(() => {
   removeTapFromHook(hook, 'example');
}, 3000)

// remove
function removeTapFromHook(hook, tapName) {
    const index = hooks.taps.findIndex(tap => tap.name === tapName);
    if (index > -1) {
        hooks.taps.splice(index, 1);
    }
}

We only need remove the tap from the private variable taps.

@sokra
Copy link
Member

sokra commented Feb 19, 2021

That's private.

But anyway if you do that call hook._resetCompilation() to update the generated code.

@sokra sokra closed this as completed Feb 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants