javascript - Node : Fully executing websocket responses sequentially with async calls

标签 javascript node.js websocket async-await

下面是我目前正在使用的一个简单示例:一个 websocket 流,它在使用传入数据时执行一些异步调用作为逻辑的一部分。我正在使用 Promise 化的 setTimeout 函数模拟异步调用:

function someAsyncWork() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('async work done');
      }, 5);
    });
}
  
async function msg() {
    const msg = await someAsyncWork();
    console.log(msg)
}

const main = async() => {

    web3.eth.subscribe('pendingTransactions').on("data", async function(tx){
        console.log('1st print: ',tx);
        await msg();
        console.log('2nd print: ',tx);
    })
}

main();

运行上面的结果在控制台输出如下:

1st print:  0x8be207fcef...
1st print:  0x753c308980...
1st print:  0x4afa9c548d...
async work done
2nd print:  0x8be207fcef...

async work done
2nd print:  0x753c308980...

async work done
2nd print:  0x4afa9c548d...
.
.
.

我知道这里发生了什么。执行“第一次打印”,然后等待每条数据响应的异步调用。 “第二次打印”仅在“异步工作完成”发生后执行。 然而,这并不是我想要的。

我的逻辑有条件,其中每个数据响应将首先使用全局变量来检查条件,然后在满足条件时进行一些异步工作。问题是在某些情况下,某些数据响应会继续执行并执行不应该执行的异步工作:Nodejs 的事件循环没有机会将一些先前数据响应的异步调用从回调队列传输到调用堆栈,因为堆栈太忙于处理新传入的数据。这意味着在处理新传入数据之前,“第二次打印”尚未执行(其中更新了全局变量)。我想 someAsyncWork 仅在 websocket 中有空闲时间且没有数据传入时才会解析。

我的问题是:有没有办法确保完整,每条新数据的顺序处理?理想情况下,控制台输出看起来像这样:

1st print:  0x8be207fcef...
async work done
2nd print:  0x8be207fcef...

1st print:  0x753c308980...
async work done
2nd print:  0x753c308980...

1st print:  0x4afa9c548d...
async work done
2nd print:  0x4afa9c548d...
.
.
.

最佳答案

你可以有一个类似队列的 promise ,不断积累 promise 以确保它们按顺序运行:

let cur = Promise.resolve();

function enqueue(f) {
    cur = cur.then(f);
}

function someAsyncWork() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('async work done');
      }, 5);
    });
}
  
async function msg() {
    const msg = await someAsyncWork();
    console.log(msg);
}

const main = async() => {

    web3.eth.subscribe('pendingTransactions').on("data", function(tx) {
        enqueue(async function() {
            console.log('1st print: ',tx);
            await msg();
            console.log('2nd print: ',tx);
        });
    })
}

main();

关于javascript - Node : Fully executing websocket responses sequentially with async calls,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65571719/

相关文章:

javascript - 从 Slack 自动打开链接

javascript - "TypeError: this is not a typed array.with"Node.js 中的 WS.js

node.js - 在我的 Mongoose 模式中添加一个数组

node.js - 验证 JWT 在中间件中使用是否有效?

javascript - 运行扩展类中的构造函数

authentication - 如何验证客户端和服务器位于不同域的 websocket 连接?

sockets - 了解WebSockets

javascript - Backbone.js:在集合中使用模型事件时不会触发

javascript - 是否可以使用 AngularJS 在 ng-click 中添加 ng-repeat $index 值?

php - 如何从逗号分隔的字符串变量中删除值?