gpt4 book ai didi

JavaScript 双重空检查和锁定

转载 作者:行者123 更新时间:2023-11-30 12:29:29 24 4
gpt4 key购买 nike

在有线程和锁的语言中很容易通过检查变量的值来实现延迟加载,如果为空则锁定下一段代码,再次检查值然后加载资源并分配。这可以防止它被多次加载并导致第一个线程之后的线程等待第一个线程完成所需的操作。

伪代码:

  if(myvar == null) {
lock(obj) {
if(myvar == null) {
myvar = getData();
}
}
}
return myvar;

JavaScript 在单线程中运行,但是,它仍然存在此类问题,因为在一个调用等待阻塞资源时异步执行。在这个 Node.js 示例中:

var allRecords;
module.exports = getAllRecords(callback) {
if(allRecords) {
return callback(null,allRecords);
}

db.getRecords({}, function(err, records) {
if (err) {
return callback(err);
}

// Use existing object if it has been
// set by another async request to this
// function
allRecords = allRecords || partners;

return callback(null, allRecords);
});
}

我懒惰地在第一次调用此函数时从一个小型数据库表中加载所有记录,然后在后续调用中返回内存中的记录。

问题:如果同时向该函数发出多个异步请求,则该表将不必要地从数据库中多次加载。

为了解决这个问题,我可以通过创建一个 var lock; 变量并在加载表时将其设置为 true 来模拟锁定机制。然后我会将其他异步调用放入 setTimeout() 循环并每隔(比如)1 秒检查一次此变量,直到数据可用,然后让它们返回。

该解决方案的问题是:

  1. 它很脆弱,如果第一个异步调用抛出并且没有解除锁定怎么办。
  2. 在放弃之前我们循环回计时器多少次?
  3. 计时器应该设置多长时间?在某些环境中,1 秒可能太长且效率低下。

是否有在 JavaScript 中解决此问题的最佳实践?

最佳答案

在第一次调用服务时,初始化一个数组。开始获取操作。创建一个 Promise,将其存储在数组中。

在后续调用中,如果数据存在,则返回一个已经完成的 Promise。如果不是,则向数组添加另一个 Promise 并返回它。

当数据到达时,解析列表中所有等待的 Promise 对象。 (一旦数据存在,您就可以丢弃列表。)

关于JavaScript 双重空检查和锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28202960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com