我试图在触发EventEmitter事件时解决一个承诺。
contains函数接受一个参数并将其添加到堆栈中。然后将项目从堆栈中取出以进行任意处理,并触发success
或error
事件。
public async processData(payload: Payload) {
// Push data onto a stack
this._myStack.push(payload);
return new Promise((resolve, reject) => {
myEventEmitter.on('processSuccess', data => {
resolve(data);
});
myEventEmitter.on('processError', error => {
reject(error);
});
});
}
问题是每次将项添加到堆栈时都会添加一个新的侦听器。这意味着当发出processSuccess
或processError
事件时,将为堆栈中的每个项目返回承诺。
示例:如果堆叠中有11个项目并且发出processSuccess
,则data
将返回11次。
当发布其中一个事件而没有为堆栈中的每个项目返回时,是否有办法解决一个承诺?也就是说,如何在不为每个事件创建一堆事件侦听器的情况下实现此目的?
答案 0 :(得分:0)
使用事件命名空间。参考https://css-tricks.com/namespaced-events-jquery/
为事件创建某种动态命名空间,并对该命名空间运行检查以匹配公共事件侦听器。在任何命名空间匹配时解析promise。
答案 1 :(得分:0)
所以基本上为了得到一个好的答案,我需要更多的信息,但总的来说,你可以做到以下几点:
因此,基于您的有效负载对象应该是这样的:
{"id": ..., ....}
响应数据对象
class MyClass {
private _myStack: Array<Payload>;
private _promisesFunctions: Array<any>;
constructor() {
myEventEmitter.on('processSuccess', data => {
this._promisesFunctions[data.id].resolve(data);
});
myEventEmitter.on('processError', error => {
this._promisesFunctions[error.id].reject(error);
});
}
public async processData(payload: Payload) {
// Push data onto a stack
this._myStack.push(payload);
return await new Promise(async (resolve, reject) => {
this._promisesFunctions[payload.id] = { resolve, reject };
});
}
}
错误数据对象
{{1}}
您可以轻松地执行以下操作:
{{1}}&#13;
如果您没有这种可能性,或者您无法控制这3个对象,请提供所有这3个对象的示例或至少有关此问题的更多信息,我会更新我的回复
答案 2 :(得分:0)
假设您可以使用随事件发送的data
本身的有效负载标识信息(成功和错误),那么您可以这样做:
public processData(payload: Payload) {
// Push data onto a stack
this._myStack.push(payload);
return new Promise((resolve, reject) => {
function resolver(data) {
// if this event belongs to this payload
if (data.payload === payload) {
resolve(data);
clearHandlers();
}
}
function rejecter(error) {
// if this event belongs to this payload
if (error.payload === payload) {
reject(error);
clearHandlers();
}
}
// clear event handlers
function clearHandlers() {
myEventEmitter.removeListener('processSuccess', resolver);
myEventEmitter.removeListener('processError', rejecter);
}
myEventEmitter.on('processSuccess', resolver);
myEventEmitter.on('processError', rejecter);
});
}
如果您无法确定哪个有效负载与哪个事件相对应,那么使用此常规结构的唯一方法是永远不要将相同的myEventEmitter
用于多个processData()
操作时间。这是因为您需要确保在processSuccess
或processError
事件发生时,您确切知道它属于哪个有效负载。您必须知道,以避免同时在飞行中的单独异步操作之间的交叉耦合。这可以通过四种方式实现:
myEventEmitter
对象。myEventEmitter
的异步操作同时在飞行中。对于上面的选项#2或#3,您可以使用以下代码:
public processData(payload: Payload) {
// Push data onto a stack
this._myStack.push(payload);
return new Promise((resolve, reject) => {
function resolver(data) {
resolve(data);
clearHandlers();
}
function rejecter(err) {
reject(error);
clearHandlers();
}
// clear event handlers
function clearHandlers() {
myEventEmitter.removeListener('processSuccess', resolver);
myEventEmitter.removeListener('processError', rejecter);
}
myEventEmitter.on('processSuccess', resolver);
myEventEmitter.on('processError', rejecter);
});
}