Javascript 如何实现异步锁或者是全局单例?

Javascript 如何实现异步锁或者是全局单例?

我想要通过 JS 实现全局单例的对象缓存,但似乎都没有很好的解决办法。

目前环境:node + vue 浏览器端运行

let cache = [];

async function getUser(id){

return new Promise((resolve) => {

if(Object.prototype.hasOwnProperty.call(cache, id)){

return resolve(cache[id])

}

setTimeout(() => {

const obj = {

id:id,

name:Math.random() .toString(36)

}

cache[id] = obj

resolve(obj)

}, 200);

})

}

如,上面代码是通过ID获取一个用户对象,而这个用户对象本想缓存起来,反复利用。其中的setTimeout是表示从网络资源获取或者是从数据库获取都将会是异步操作反馈。

> getUser(1).then(data=>console.log(data))

getUser(1).then(data=>console.log(data))

getUser(1).then(data=>console.log(data))

< Promise {<pending>}

VM323:1 {id: 1, name: "0.gayf057xhjo"}

VM323:2 {id: 1, name: "0.owi31fi79z"}

VM323:3 {id: 1, name: "0.3bya3r4poxn"}

如果连续执行多次,就会产生多个"用户对象", 通过名字鉴别,是因为缓存还未写入,导致后面的函数也会进入重新获取对象产生"新对象",前者先执行完毕写入的缓存对象也会被后来者覆盖,这是不被允许的。

如果之后再次获取,命中缓存了,获取到最后一次存储的缓存对象,前几次冗余的就会失效。

问题:

这个逻辑中,我想解决唯一缓存对象,或者是异步锁的实现,能够有效阻塞后来者,但不丢弃。

至于为什么要一起异步并发执行,而不逐个执行,是因为实际应用场景中,可能是有多个模块某个瞬间同时需要这块数据造成的。

希望各位大佬帮忙看看,提供思路方法。


回答:

getUser连续运行多次,因为同步的原因,没有走上面的if,都走了下面的定时器,2s后添加cache(此时才有的cache[id],在运行getUser才会走if里)并resolve,所以每一次都不一样。改的话可以这么改,cache中不存放具体数据,而是存放promise实例

let cache = {};

async function getUser(id){

return cache[id] || (cache[id] = new Promise(resolve => {

setTimeout(() => {

const obj = {

id:id,

name:Math.random() .toString(36)

}

resolve(obj)

}, 200);

}))

}

getUser(1).then(data=>console.log(data))

getUser(1).then(data=>console.log(data))

getUser(1).then(data=>console.log(data))


回答:

https://github.com/ide/await-...


回答:

直接在cache[id]放个promise,检查这个promise的状态就知道要不要反复设置

以上是 Javascript 如何实现异步锁或者是全局单例? 的全部内容, 来源链接: utcz.com/p/935913.html

回到顶部