首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为并发调用返回false的简单锁- javascript

为并发调用返回false的简单锁- javascript
EN

Stack Overflow用户
提问于 2020-04-09 10:47:56
回答 1查看 145关注 0票数 2

我想锁定一个异步函数,使其不能同时执行。函数只能由一个调用者执行,它应该在执行后作为输出得到true,而其他调用者在没有执行函数的逻辑内容的情况下得到false作为返回。其他人不应该等待当前调用者完成。

这就是我到目前为止所尝试的:

代码语言:javascript
运行
复制
class Lock {
    constructor() {
        this.locked = false;
    }
    lock(resolve) {
        if (this.locked) {
            resolve(false)
        }
        this.locked = true
        return
    }
    release(resolve) {
        this.locked = false;
        resolve(true)
    }


}

let lock = new Lock();

function myFunction() {
    return new Promise(resolve => {
        lock.lock(resolve);
        //do something - this takes time includes some api calls and db operations
        lock.release(resolve);
    })
}

async function callSite() {
    const executed = await myFunction();
    if(executed){
        //do something
    }
    else{
        //do another thing
    }
}

但看起来它并没有像预期的那样工作。有人能帮我改进一下吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-13 08:29:17

Promise的执行并不总是保证在解决或拒绝之后立即停止;在检查锁并退出或相应地继续promise之后,您必须返回一个布尔值。

运行下面的代码片段;它是一个包含3个按钮的示例,这些按钮具有相同的承诺和3秒的延迟。当一个按钮正在运行时,所有其他按钮都不能执行。

代码语言:javascript
运行
复制
class Lock {
  constructor() {
    this.locked = false;
  }

  lock(resolve) {
    if (this.locked) {
      resolve(false);
      return false;
    }
    this.locked = true
    return true;
  }

  release(resolve) {
    this.locked = false;
      resolve(true)
  }
}

let lock = new Lock();

function myFunction({ resultEl }) {
  resultEl.textContent = "Is running";
    
  return new Promise(resolve => {
    // Check if it's locked
    if (!lock.lock(resolve)) {
      // If it is, return and exit the function even if the promise is already resolved
      return;
    }

    // do something - this takes time includes some api calls and db operations
    // just wait 3 seconds for demontration
    setTimeout(() => {
      lock.release(resolve);
    }, 3000);
  })
}

async function callSite() {
  this.disabled = true;

  const executed = await myFunction({ resultEl : this.nextSibling });
    
  this.disabled = false;

  if (executed) {
    this.nextSibling.textContent = `Finished at ${(new Date).getTime()}`;
  }
  else {
    this.nextSibling.textContent = `Was NOT executed at ${(new Date).getTime()}`;
  }
}

document.getElementById('a-button').addEventListener('click', callSite);
document.getElementById('b-button').addEventListener('click', callSite);
document.getElementById('c-button').addEventListener('click', callSite);
代码语言:javascript
运行
复制
div {
  margin-bottom: 10px;
}

button {
  margin-right: 5px;
}
代码语言:javascript
运行
复制
<div>
  <button id="a-button">Run A</button><span></span>
</div>

<div>
  <button id="b-button">Run B</button><span></span>
</div>

<div>
  <button id="c-button">Run C</button><span></span>
</div>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61113167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档