【问题标题】:what is the best method to multi request with callback or promise on node.js在node.js上使用回调或承诺进行多请求的最佳方法是什么
【发布时间】:2019-04-26 17:14:01
【问题描述】:

我有一个情况。我使用 Node.js 连接到一个特殊的硬件。假设我有两个函数可以访问硬件。

hardware.send('command');
hardware.on('responce', callback);

起初,我创建了一个类来像这样将它与应用层接口(我在这里写了简化的代码以便更好地理解)

class AccessHardware {
    constructor() {    
    }
    updateData(callback) {        
        hardware.on('responce', callback);        
        hardware.send('command');
    }
}

现在的问题是,如果应用层有多个请求到这个访问层,它们不应该向硬件发送多个“命令”。相反,他们应该发送一个命令,一旦硬件响应命令,所有这些回调都可以被提供。

所以我更新代码如下:

class AccessHardware {
    constructor() {
        this.callbackList = [];
        hardware.on('responce', (value) => {
            while (this.callbackList.length > 0) {
                this.callbackList.pop()(value);
            }
        });        
    }
    updateData(callback) {  
        if (this.callbackList.length == 0) {                    
            hardware.send('command');
        }
        this.callbackList.push(callback);
    }
}

当然,我更喜欢用promise来处理这种情况。那么你对用 promise 编写这段代码有什么建议呢? 下一个问题,这种制作“回调列表”的方法好吗?

【问题讨论】:

  • 所以所有updateData() 调用都发送相同的命令,他们不应该在一个仍在飞行的时候发送命令?这样您就可以获得最大的命令发送速率,并且结果可以在连续调用之间任意共享?你期望结果会改变吗?如果是,共享听起来不是一个好主意,如果不是,为什么要发送多个命令而不是共享单个结果?
  • @Bergi 好吧,应用层有多个基于 Web 的客户端,因此它们可能都询问相同的命令。结果准备就绪后(大约需要 15 秒),应用程序应将结果发送给所有客户端。这就是所有命令都相同但有多个请求的原因
  • 是的,但是如果其他客户端在 30 秒后询问相同的命令,是否真的需要再次运行该命令?难道不能只返回之前发送给其他客户端的已经可用的结果吗?
  • @Bergi 不,它应该总是得到一个新的查询,因为在此期间硬件的状态可能会发生变化。
  • 好的,只是当硬件状态在 10 秒后发生变化时(当第一个命令仍在运行时),在 15 秒询问的客户端仍然得到旧的结果。这对我来说似乎有些武断,我宁愿推荐一个通用的去抖动函数,用于在固定时间后清除其缓存。

标签: node.js list callback promise


【解决方案1】:

我更喜欢使用 promise 来处理这种情况。那么你对用 promise 编写这段代码有什么建议呢?

您将在您的实例中存储一个承诺,该承诺将在所有希望共享相同结果的方法调用者之间共享:

class AccessHardware {
    constructor(hardware) {
        this.hardware = hardware;
        this.responsePromise = null;
    }
    updateData() {  
        if (!this.responsePromise) {
            this.responsePromise = new Promise(resolve => {
                this.hardware.on('responce', resolve);
                this.hardware.send('command');
            });
            this.responsePromise.finally(() => {
                this.responsePromise = null; // clear cache as soon as command is done
            });
        }       
        return this.responsePromise;
    }
}

顺便说一句,如果hardware 是一个全局变量,那么这里没有理由使用class

目前制作“回调列表”的解决方案好吗?

是的,对于无承诺的方法也可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 2019-01-23
    • 2020-04-13
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多