【问题标题】:JS safety when accessing variables outside of the async function访问异步函数之外的变量时的 JS 安全性
【发布时间】:2021-03-07 18:42:39
【问题描述】:

我这里有个async函数,因为messageQueue在外面改了,想知道这样写是否安全。

this.messageQueue.push(message1);
onChatMessage();
... // some other code
this.messageQueue.push(message2);
onChatMessage();
... // some other code
this.messageQueue.push(message3);
onChatMessage();
...

onChatMessage: async function () {
    if (this.isProcessMsgQ) { return; }
    this.isProcessMsgQ = true;
    for (let i = 0; i < this.messageQueue.length; i++) {
        const msg = this.messageQueue[i];
        try {
            await this.processMessage(msg);
        } catch (err) {
        }
    }
    this.messageQueue = [];
    this.isProcessMsgQ = false;
},

我担心的是,对于thread1,在this.messageQueue = []; 之后和this.isProcessMsgQ = false; 之前,thread2 能否完成从将message2 添加到队列中、进入onChatMessage、检查this.isProcessMsgQ 的过程,然后返回? 如果是,那么有message2不会被处理的情况,有什么办法处理吗?

谢谢!

【问题讨论】:

  • 没有别的可以运行right after this.messageQueue = []; and before this.isProcessMsgQ = false;同步代码同步运行
  • 还有,什么是“thread1”和“thread2”……你在用workers吗?
  • JavaScript 是单线程的。它只能安排将来​​调用的函数。在您的具体示例中,忽略第一个onChatMessage() 调用的// some other codethis.message = []; 甚至不会执行,直到最后一个onChatMessage() 调用发生。另见developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
  • thread1和thread2是指onChatMessage分别对message1和message2的调用吗?
  • @Bravo,就像@richytong 说的,thread1onChatMessage 的第一个调用,thread2 是第二个调用,等等

标签: javascript multithreading async-await thread-safety


【解决方案1】:

在 for 循环开始和设置 this.messageQueue = [] 之间可能会丢失消息。当您重新分配 this.messageQueue 时,在该时间范围内添加的任何消息都将丢失。为防止这种情况发生,请使用 Promise 跟踪消息执行的完成情况,在任何执行开始之前刷新队列。

onChatMessage: function () {
    if (this.isProcessMsgQ) { return; }
    this.isProcessMsgQ = true;
    const tmp = this.messageQueue
    this.messageQueue = []
    this.executingAll = Promise.all(
      tmp.map(msg => this.processMessage(msg).catch(() => {}))
    ).then(() => {
      this.isProcessMsgQ = false
    })
},

【讨论】:

    猜你喜欢
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多