我们正在使用事件来管理Node.js应用程序中的工作流。我想知道我们是否可以用承诺代替事件?我对事件的看法非常像ike回调,其中事件名称就像要调用的函数名称一样,因此切换到promises会很好吗?需要有经验的人对此发表意见。
add : function(req, res, next){
var workflow = req.app.utility.workflow(req, res);
workflow.on('checkPermissions', function(){
// If admin is permitted to add Widget template
var isPermitted = permissions.getPermission(req.user.group, "widget-template", "add");
console.log("Is permitted to add WidgetTemplate:-", isPermitted);
if(!isPermitted)
workflow.emit('exception', 'Not Permitted');
else
workflow.emit('validate');
});
workflow.on('validate', function(){
if(!req.body.wID)
workflow.outcome.errfor.wID = 'required';
if(!req.body.wname){
workflow.outcome.errfor.wname = 'required';
}
if(workflow.hasErrors())
{
workflow.outcome.errfor.msg = 'Please fill all the fields';
return workflow.emit('response');
}
else
workflow.emit('add');
});
workflow.on('add', function(){
var WidgetTemplate = req.app.db.models.WidgetTemplate;
var fieldsToSet = new WidgetTemplate({
widgetTempID : req.body.wID,
name : req.body.wname,
devType : req.body.devTypes,
sensors : req.body.sensors,
properties : req.body.properties? req.body.properties : [],
multiple_devices : req.body.multiple_devices? req.body.multiple_devices : false,
added_by : req.user.id
});
console.log("FieldsToset", fieldsToSet);
fieldsToSet.save()
.then(
() => {
console.log("Widget Template created...");
workflow.emit('response');
}
)
.catch((err) => {
console.log("Some error occurred", err.code);
if(err.code == 11000)
workflow.emit('exception', 'Duplicate widget template ID');
else
workflow.emit('exception', err);
});
});
workflow.emit('checkPermissions');
}
答案 0 :(得分:1)
主要缺点是承诺只能解决一次。如果您的事件属于此类事件,那么可以肯定地可以使用诺言。但是许多事件想发生多次,而用诺言来表达它并不是一个好方法。
一种替代方法是使用Observables,它与Promise相似,但是可以发出任意次数。它们既强大又灵活,但是确实有很大的学习曲线。 rxjs是一种流行的可观察对象库:https://github.com/ReactiveX/rxjs
答案 1 :(得分:1)
事件侦听器只能用应诺(promise)来替换仅应发出一次的事件,例如可以使用事件发射器once
方法。否则,应创建多个承诺。
p-event
处理这两种情况。它允许对一次发出的事件进行承诺:
const result = await pEvent(emitter, 'finish');
否则,它允许根据需要使用异步迭代器和for-await-of
遍历Promise:
const asyncIterator = pEvent.iterator(emitter, 'data', {
resolutionEvents: ['finish']
});
for await (const event of asyncIterator) {
console.log(event);
}
正如另一个答案提到的那样,可观察值是在这里可能有用的另一种模式。可观察者能够做到承诺所能做的所有事情,并且以简洁为代价。由于它们可以发出多个值,因此侦听发出的事件是它们的一个好用例。