gpt4 book ai didi

javascript - EventEmitter 事件处理程序的延迟附加模式?

转载 作者:太空宇宙 更新时间:2023-11-04 00:59:09 25 4
gpt4 key购买 nike

在事件生成后附加事件处理程序有一个看似众所周知的问题。这主要是在调用遵循返回 EventEmitter 模式的函数时出现的问题,例如:

var EventEmitter = require('events').EventEmitter;

function doSomethingAsync() {
var ev = new EventEmitter(),
something = null;

// Caller will never see this event because its
// handler is bound after fact.

if(!something) {
ev.emit('error', 'Something is null!');
return ev;
}

return ev;
}

var res = doSomethingAsync();

res.on('error', function(s) {
console.log('Error returned: ' + s);
});

这将返回一个未处理的错误异常,因为在发出 error 时,尚未附加它的处理程序:

sasha@peacock:~$ node test.js
events.js:87
throw Error('Uncaught, unspecified "error" event.');
^
Error: Uncaught, unspecified "error" event.
at Error (native)
at EventEmitter.emit (events.js:87:13)
at doSomethingAsync (/home/sasha/test.js:11:6)
at Object.<anonymous> (/home/sasha/test.js:18:11)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:124:16)

我能想到的唯一解决方案是在调用端创建一个 EventEmitter,提前绑定(bind)处理程序,并将其传递给函数:

var EventEmitter = require('events').EventEmitter;

function doSomethingAsync(ev) {
var something = null;

// Caller will never see this event because its
// handler is bound after fact.

if(!something) {
ev.emit('error', 'Something is null!');
}
};

var res = new EventEmitter();

res.on('error', function(s) {
console.log('Error returned: ' + s);
});

doSomethingAsync(res);

不过,这看起来不优雅且困惑。通过第一个方法应用的异步操作的事件处理程序起作用的唯一原因是,所讨论的操作通常需要比函数返回更长的时间才能完成。这使得调用者有时间将事件处理程序应用到返回的 EventEmitter

肯定有一个首选模式、习惯用法或隐藏的 JavaScript 或 Node 功能可以更好地处理这种情况吗?

我认为一种方法是不使用 EventEmitters 来传输验证错误或其他可能立即发生的错误,而只是返回其他内容。但我仍然认为这并不能解决根本问题;该模型在 Node 文档和其他地方广泛描述,它依赖于这样的假设:完成异步操作所需的时间比返回 EventEmitter 后绑定(bind)事件处理程序所需的时间更长。大多数时候,这可能是真的,但不能保证是真的。

这就是为什么我认为必须有更好的方法。如果没有,那么有关 EventEmitters 最佳实践使用的 Node 文档就会非常具有误导性。当然有更好的方法吗?

最佳答案

您可以使用process.nextTick来推迟当前调用堆栈执行后的事件发出。举个例子:

var EventEmitter = require('events').EventEmitter;

function doSomethingAsync() {
var ev = new EventEmitter(),
something = null;

// Caller will see this event because it
// will be emitted after current call stack

if(!something) {
process.nextTick(function() {
ev.emit('error', 'Something is null!');
});
return ev;
}

return ev;
}

var res = doSomethingAsync();

res.on('error', function(s) {
console.log('Error returned: ' + s);
});

关于javascript - EventEmitter 事件处理程序的延迟附加模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27809517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com