Add an base function callback for a specific event with optional filtering.  If the function returns a
        coroutine, it will be awaited.

        Args:
            evnt (str):         An event name
            func (function):    A callback function to receive event tufo

        Examples:

            Add a callback function and fire it:

                async def baz(event):
                    x = event[1].get('x')
                    y = event[1].get('y')
                    return x + y

                d.on('foo', baz)

                # this fire triggers baz...
                await d.fire('foo', x=10, y=20)

        Returns:
            None:

def on(self, evnt, func, base=None):
        '''
        Add an base function callback for a specific event with optional filtering.  If the function returns a
        coroutine, it will be awaited.

        Args:
            evnt (str):         An event name
            func (function):    A callback function to receive event tufo

        Examples:

            Add a callback function and fire it:

                async def baz(event):
                    x = event[1].get('x')
                    y = event[1].get('y')
                    return x + y

                d.on('foo', baz)

                # this fire triggers baz...
                await d.fire('foo', x=10, y=20)

        Returns:
            None:
        '''
        funcs = self._syn_funcs[evnt]
        if func in funcs:
            return

        funcs.append(func)

        if base is not None:

            def fini():
                self.off(evnt, func)

            base.onfini(fini)