一个缓存中的多个对象中的多个异步获取器

问题描述 投票:0回答:1

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(对于bc也一样?


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命名为与该属性相同的名称,因为该属性会导致递归调用(我如何使对用户透明的行为?)

什么是实现此目的的更好方法?

javascript getter
1个回答
0
投票

[有多种方法可以执行此操作,但是冒着帮助您解决没有的问题的风险(我怀疑您的整体应用程序设计中存在应在其他地方纠正的缺陷),我将解决当前的问题。] >

您的错误根源于您的财产描述-无论是以a: 1get a() ...使用相同的属性描述符(通常称为“名称”),因此您的getter重新定义了例如this.a将被引用,覆盖先前的属性描述(a: 1),其他属性bc也是如此。

我还想指出,缓存承诺再次使我认为您的某些假设是错误的-当承诺解决时,该值已经在内部缓存了。一个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常量的过程可能会访问其外部范围内的对象(变量,常量等),包括实际的高速缓存(映射)基于过程引用的结果)。

© www.soinside.com 2019 - 2024. All rights reserved.