JavaScript / NodeJS - 将promise作为扩展方法添加

时间:2017-04-18 14:16:50

标签: javascript node.js

可能有一个简单的答案,但我只需要在C#中使用扩展方法(他们甚至在JS中调用它吗?)。

我有一个使用事件的第三方库。在调用事件后,我需要一个名为的函数。我可以通过承诺轻松完成这项工作,但第三方库是在ES6之前编写的,并且没有内置的承诺。这里有一些示例代码 -

wRcon.on('disconnect', function() {
  console.log('You have been Disconnected!')
})

理想情况下,我希望能够实现这样的目标 -

wRcon.on('disconnect', function() {
  console.log('You have been Disconnected!')
}).then(wRcon.reconnect())

总结一下我的问题,如何扩展wRcon.on以允许一个promise(或其他一些回调方法)?

3 个答案:

答案 0 :(得分:2)

承诺和事件虽然表面看起来很相似,但实际上解决了Javascript中的不同问题。

Promises提供了一种方法来管理预期结果的异步操作,但是你只知道要花多长时间。

事件提供了一种管理异步操作的方法,其中可能发生,但您不知道它何时(或者甚至是否)会发生。

在Javascript中,没有简单的方法在两者之间“接口”。

但是对于你给出的例子,有一个简单的解决方案:

wRcon.on('disconnect', function() {
  console.log('You have been Disconnected!')
  wRcon.reconnect()
})

这可能不如您的解决方案那么优雅,如果您的目的是在最后添加更长的.then()处理程序链,则会发生故障,但它会完成工作。

答案 1 :(得分:0)

您可以以创建承诺的方式包装连接:

const promise = new Promise((resolve) => {
  wRcon.on('disconnect', function() {
    resolve();
  })
}).then(wRcon.reconnect())

然而,这似乎不是使用Promises的理想场所。 Promise定义了单个数据流,而不是定期的事件驱动方式来处理应用程序状态。此设置仅在断开连接后重新连接一次。

答案 2 :(得分:0)

三个/四个选项,第三个/第四个是我个人的偏好:

替换on

可以替换on对象上的wRcon

const original_on = wRcon.on;
wRcon.on = function(...args) {
    original_on.apply(this, args);
    return Promise.resolve();
};

...你可以在展示时使用几乎(注意_ =>):

wRcon.on('disconnect', function() {
  console.log('You have been Disconnected!');
}).then(_ => wRcon.reconnect());

...但我对此非常谨慎,尤其是因为wRcon的其他部分可能会调用on并期望它具有不同的返回值(例如{{ 1}},因为this通常是可链接的操作。)

添加新方法(on

或者您可以添加方法:

onAndAfter

...然后

const original_on = wRcon.on;
wRcon.onAndAfter = function(...args) {
    wRcon.on.apply(this, args);
    return Promise.resolve();
};

...但我不喜欢修改其他API的对象。

实用程序方法(独立,或wRcon.onAndAfter('disconnect', function() { console.log('You have been Disconnected!'); }).then(_ => wRcon.reconnect());

相反,我想我会给自己一个实用功能(“可以”“):

Function.prototype

...然后像这样使用它:

const after = (f, callback) => {
    return function(...args) {
        const result = f.apply(this, args);
        Promise.resolve().then(callback).catch(_ => undefined);
        return result;
    };
};

创建一个新函数传递给wRcon.on('disconnect', after(function() { console.log('You have been Disconnected!'); }, _ => wRcon.reconnect())); ,当调用时,(ab)使用on来调度回调(作为当前macrotask结束的微任务;使用{{ 1}}如果你只是想让它成为一个普通的[宏]任务)。

您可以将Promise添加到setTimeout的内容,有点像after

Function.prototype

......然后:

bind

是的,我知道具有讽刺意味的是(一方面)“我不喜欢修改其他类似API的对象”,然后显示修改Object.defineProperty(Function.prototype, "after", { value: function(callback) { const f = this; return function(...args) { const result = f.apply(this, args); Promise.resolve().then(callback).catch(_ => undefined); return result; }; } }); 的根API的选项。 ; - )