您可以在Node.js中用Promise替换事件吗?

时间:2018-10-02 12:18:53

标签: javascript node.js events promise

我们正在使用事件来管理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');

}

2 个答案:

答案 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);
}

正如另一个答案提到的那样,可观察值是在这里可能有用的另一种模式。可观察者能够做到承诺所能做的所有事情,并且以简洁为代价。由于它们可以发出多个值,因此侦听发出的事件是它们的一个好用例。