Update2:以下方法有效,但效果不完全
const obj = {
cached_a: 0,
cached_b: 0,
cached_c: 0,
get a() {
if (this.cached_a == 0) this.cached_a = getA();
return this.cached_a;
}
}
const getA = function() {
console.log('calcing...')
return 25;
};
console.log('1: ' + obj.a);
console.log('2: ' + obj.a);
在我的程序中,该值不是第二次计算,而是从缓存中发回。
$ node get-set.js
calcing...
1: 25
2: 25
例如,我的getA()
必须为async
。但是,我知道ES6不允许async getters
。如果是正确的话,我将不胜感激,可以实现上述目标(假设getA()
必须为async
。
第二,如何使用多个getters
(对于b
和c
也一样?
Update1: getA()
(希望其他吸气剂)从服务器(这是所有浏览器端)获取值,并且我不希望这种情况发生,如果该值已被检索一次并且是缓存在浏览器中。
我试图在一个对象中理解并实现getter/setter
,该对象将充当async
进程返回的值的缓存。
'use strict';
// my desired pseudo-object with incorrect code
const obj = {
a: 0,
b: 0,
c: 0,
get a() {
if (this.a == 0) this.a = await getA();
return this.a;
}
get b() {
if (this.b == 0) this.b = await getB();
return this.b;
}
get c() {
if (this.c == 0) this.c = await getA();
return this.c;
}
};
const getA = async function() { … };
const getB = async function() { … };
const getC = async function() { … };
很明显,以上几个问题:
getters
(或者我可以吗?); getters
命名为与该属性相同的名称,因为该属性会导致递归调用(我如何使对用户透明的行为?)什么是实现此目的的更好方法?
[有多种方法可以执行此操作,但是冒着帮助您解决没有的问题的风险(我怀疑您的整体应用程序设计中存在应在其他地方纠正的缺陷),我将解决当前的问题。] >
您的错误根源于您的财产描述-无论是以a: 1
或get a() ...
使用相同的属性描述符(通常称为“名称”),因此您的getter重新定义了例如this.a
将被引用,覆盖先前的属性描述(a: 1
),其他属性b
和c
也是如此。
我还想指出,缓存承诺再次使我认为您的某些假设是错误的-当承诺解决时,该值已经在内部缓存了。一个Promise对象仅调用一次resolve
,但是每次您通过Promise.prototype.then
附加一个回调时,Promise将使用缓存的解析值来调用您的回调。 await
只是语法糖,解释器在内部按顺序运行您的代码,但是请放心,每当计算await
表达式时,将使用一次“已解析”的缓存值。
我想告诉你的是,缓存承诺没有意义。
您可以
缓存是过程评估。意味着您提供了一个不变的条件,即过程调用(不带参数,使缓存更简单)将始终返回相同的值,该值与缓存中的过程相关联:const cached = (() => { const cache = new WeakMap(); return (procedure) => { var result = cache.get(procedure); return result || (cache.set(procedure, result = procedure()), result); } })();
现在,如果您将一个昂贵的操作封装在一个函数中,例如说
request_foobar
,则可以使用request_foobar()
表达式,而不是使用将每次执行一次都会返回相同结果的冗长操作的cached(request_foobar())
表达式,如果有缓存命中,则将从缓存中获取先前的结果;如果没有缓存命中,则调用该过程并返回缓存的结果。
cached
的实现取决于所谓的“关闭”函数-分配给cached
常量的过程可能会访问其外部范围内的对象(变量,常量等),包括实际的高速缓存(映射)基于过程引用的结果)。