使用 es6 模块创建自定义"event listener"



我们正在努力在Javascript上创建自定义事件侦听器。尝试了一些示例,但无法调用自定义事件侦听器。代码示例:

事件.js

function init() {
return new Promise(() => {
console.log('successfully initialized!');
});
}
// this symbolizes some event occurring randomly. in reality, this will eventually be
// something like a webhook getting hit, or a websocket, etc. for now we just use
// setTimeout to simulate this event coming in at some time after init has been called
setTimeout(on, 15000);
// on is called anytime any event occurs. in this example, we hardcode that event1 occurred
function on() {
console.log('event1 occurred in events.js');
return 'event1';
}​
const events = {
init,
on,
};
export default events;

索引.js

events.init(() => {
// here we should see console log about successful initialization
}).then(() => {
// here, we want to "listen" for event1 to occur
events.on('event1', () => {
console.log('we were notified about event1 happening!');
});
});

在此示例中,我们看到以下内容显示在浏览器控制台中

successfully initialized!

然后几秒钟后:

event1 occurred in events.js

如 index 中"event1"的示例回调代码所示.js永远不会调用,而是调用来自 events.js 的 "on" 函数。 我们需要的是一个自定义事件侦听器来工作,以便我们可以从 index.js 控制台调用"event1".log应该显示

we were notified about event1 happening!

感谢您查看问题并帮助解决问题。

我会说这里几乎没有问题。

1. 未解决的承诺

首先,您没有解析承诺,这意味着永远不会调用then回调。

因此,首先应将init方法更新为如下:

function init() {
return new Promise((resolve) => {
console.log('successfully initialized!');
// when you're done with your stuff, tell outside
resolve()
});
}

2. 跟踪回调

此外,您没有跟踪不同类型事件的不同回调。on 方法应将元组事件回调保存在适当的映射中,如下所示:

const handlers = {}
function on(event, callback) {
handlers[event] = callback;
}

3. 事件发射

我认为您缺少的最后一件事是事件的"发射"概念。当发生某些特定事件时,您应该发出适当的事件。比,如果它已被注册为回调,您将调用它。

因此,您需要向eventsapi 添加第三个emit方法,如下所示:

function emit(event) {
const callback = handlers[event];
// if we registered a callback before, and it is a function,
// let's call it  
if ( callback && typeof callback === 'function' )
callback()
}

您的最终导出将变为:

const events = {
init,
on,
emit
};

使用此新方法,可以将发出事件的调用模拟为正在注册的事件event1

setTimeout(() => emit('event1'), 5000);

它似乎像一个魅力:)

编辑

我不确定这是否可能是 @Shehzad Nizamani 要求的确切用例,但如果没有给出特定事件,我们可以emit触发所有注册的回调,例如:

setTimeout(emit, 5000)
function emit(event) {
if ( event ) {
const callback = handlers[event];
// if we registered a callback before, and it is a function,
// let's call it  
if ( callback && typeof callback === 'function' )
callback()
// if no event is given, we trigger all the callbacks
} else {
const callbacks = Object.values(handlers)
callbacks.forEach(callback => {
if ( typeof callback === 'function' )
callback()
})
}
}

function init() {
return new Promise((resolve) => {
console.log('successfully initialized!');
// when you're done with your stuff, tell outside
resolve()
});
}
// emit a specific event to trigger the relative callback
setTimeout(() => emit('event1'), 10000);
setTimeout(emit, 5000);
// we need to keep track of a map
// between event types and their callback
const handlers = {}
function on(event, callback) {
handlers[event] = callback;
}
// we need a new api that triggers registered callbacks
function emit(event) {
if ( event ) {
const callback = handlers[event];
// if we registered a callback before, and it is a function,
// let's call it  
if ( callback && typeof callback === 'function' )
callback()
// if no event is given, we trigger all the callbacks
} else {
const callbacks = Object.values(handlers)
callbacks.forEach(callback => {
if ( typeof callback === 'function' )
callback()
})
}
}
const events = {
init,
on,
emit
};
events.init(
() => {
// here we should see console log
//about successful initialization
}
).then(
() => {

// here, we want to "listen" for event1 to occur
events.on('event1', () => {
console.log('we were notified about event1 happening!');
});
}
);

最新更新