简单锁 returns false 对于并发调用 - javascript
Simple Lock That returns false for concurrent calls - javascript
我想锁定异步函数以防止其同时执行。该函数只能由一个调用者执行,它应该在执行后得到 true 作为输出,而其他人得到 false 作为 return 而不执行函数的逻辑内容。其他人不应该等待当前调用者完成。
这是我到目前为止尝试过的:
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
}
}
但似乎没有按预期工作。谁能帮我改进一下?
承诺执行并不总是保证在解决或拒绝后立即停止;在检查锁定并退出或相应地继续承诺后,您必须 return 一个布尔值。
运行 下面的片段;这是一个具有相同承诺和 3 秒延迟的 3 个按钮的示例。当一个按钮是运行时,其他的都不能执行。
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);
div {
margin-bottom: 10px;
}
button {
margin-right: 5px;
}
<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>
我想锁定异步函数以防止其同时执行。该函数只能由一个调用者执行,它应该在执行后得到 true 作为输出,而其他人得到 false 作为 return 而不执行函数的逻辑内容。其他人不应该等待当前调用者完成。
这是我到目前为止尝试过的:
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
}
}
但似乎没有按预期工作。谁能帮我改进一下?
承诺执行并不总是保证在解决或拒绝后立即停止;在检查锁定并退出或相应地继续承诺后,您必须 return 一个布尔值。
运行 下面的片段;这是一个具有相同承诺和 3 秒延迟的 3 个按钮的示例。当一个按钮是运行时,其他的都不能执行。
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);
div {
margin-bottom: 10px;
}
button {
margin-right: 5px;
}
<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>