Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 您如何基于另一个商店';s的苗条价值?_Javascript_Store_Svelte - Fatal编程技术网

Javascript 您如何基于另一个商店';s的苗条价值?

Javascript 您如何基于另一个商店';s的苗条价值?,javascript,store,svelte,Javascript,Store,Svelte,今天我在Svelte上写了我的第一个应用程序,在尝试创建一个非平凡的商店系统时,我遇到了一个基本的逻辑问题 正如问题标题所说,我正在努力寻找一种方法来协调存储更新,其中一个存储以某种方式更新,具体取决于另一个存储的当前值 文档说明可以使用get获取存储的状态值,如下所示: import { get } from 'svelte/store'; const value = get(store); 但这些文件也指出: 通常,您应该通过订阅存储并在其随时间变化时使用该值来读取存储的值。有时,您可能需

今天我在Svelte上写了我的第一个应用程序,在尝试创建一个非平凡的商店系统时,我遇到了一个基本的逻辑问题

正如问题标题所说,我正在努力寻找一种方法来协调存储更新,其中一个存储以某种方式更新,具体取决于另一个存储的当前值

文档说明可以使用
get
获取存储的状态值,如下所示:

import { get } from 'svelte/store';
const value = get(store);
但这些文件也指出:

通常,您应该通过订阅存储并在其随时间变化时使用该值来读取存储的值。有时,您可能需要检索未订阅的存储的值。get允许您这样做。 其工作原理是创建订阅、读取值,然后取消订阅。因此,不建议在热代码路径中使用它

这让我想知道是否应该避免这种使用模式,即在没有实际订阅的情况下使用“get”获取存储的状态值,但我不确定如何协调对多个存储的更新


为了帮助解释,我写了一些我认为可以做到这一点的例子,但所有这些例子似乎都不理想

在我的例子中,我正在使用一个应用程序,你必须射击一个目标,但是目标的生命会随着你左轮手枪枪膛中第一种弹药的数量而下降

该应用程序以输入侦听器开始

#############################################################
# Step 1: Create an input listener
#############################################################

const keyboardListener = (() => {
    const subscribers = new Map();
    document.addEventListener('keyup', event => {
        if (event.code === 'Space') {
            [...subscribers].forEach(sub => sub({ eventType: 'fire' }));
        }
    });
    function subscribe(fn) {
        this.subscribers.set(fn, fn);
        return () => {
            this.subscribes.delete(fn);
        };
    }
    return {
        subscribe,
    };
})();
现在让我们尝试创建一个商店

#############################################################
# Step 2a: Store architecture pattern 1: The problem
#############################################################

export const target = writable({
    name: 'cow',
    hp: 100,
});

export const ammo = writable([
    {
        type: 'armourPiercing',
        damage: 20,
    },
    {
        type: 'explosive',
        damage: 50,
    },
    {
        type: 'flash',
        damage: 1,
    }
]);

keyboardListener.subscribe(() => {

    // If we have ammo, get the first ammo and reduce the cows HP.
    target.set(currentTargetValue => ({
        ...currentTargetValue,
        hp: currentTargetValue.hp - ammoDamage // Where does ammoDamage come from?
    }));
});
上面的存储的问题是,我不确定在目标存储的更新回调函数中如何获取弹药存储的值

我已经意识到,我可以通过将应用商店作为一个大的、单一的东西来克服这一点。然后,在执行更新时,我可以始终获得其所有状态

#############################################################
# Step 2b: Store architecture pattern 2: One big store
# (So we can access the current value of both stores during
# the update)
#############################################################

export const wholeAppStore = writable({
    target: {
        name: 'cow',
        hp: 100,
    },
    ammo: [
        {
            type: 'armourPiercing',
            damage: 20,
        },
        {
            type: 'explosive',
            damage: 50,
        },
        {
            type: 'flash',
            damage: 1,
        }
    ]
});

keyboardListener.subscribe(() => {

    // If we have ammo, get the first ammo and reduce the cows HP.
    wholeAppStore.set(currentWholeAppStoreValue => {
        const newAmmo = JSON.parse(JSON.stringify(currentWholeAppStoreValue.ammo));
        const firstAmmo = newAmmo.pop();
        const newTarget = JSON.parse(JSON.stringify(currentWholeAppStoreValue.target));
        newTarget.hp -= firstAmmo.damage;
        return {
            target: newTarget,
            ammo: newAmmo,
        };
    });
});
但拥有一个大型的单一应用商店似乎并不明智。为其编写更新是很尴尬的,我想知道它在性能方面是否也不是很好

因此,让我们尝试使用
get
函数

#############################################################
# Step 2c: Store architecture pattern 3: Use "get"?
#############################################################

export const target = writable({
    name: 'cow',
    hp: 100,
});

export const ammo = writable([
    {
        type: 'armourPiercing',
        damage: 20,
    },
    {
        type: 'explosive',
        damage: 50,
    },
    {
        type: 'flash',
        damage: 1,
    }
]);

keyboardListener.subscribe(() => {

    const ammoValue = get(ammo);
    const firstAmmo = [...ammoValue].pop();
    const ammoDamage = firstAmmo.damage;

    // If we have ammo, get the first ammo and reduce the cows HP.
    target.set(currentTargetValue => ({
        ...currentTargetValue,
        hp: currentTargetValue.hp - ammoDamage;
    }));
});
但由于文档中的信息,我不确定这种方法。另外,由于我只使用了
get
来获取值,弹药库没有更新以从左轮手枪室移除弹药。也许我们应该用两个单独的更新回调来完成

#############################################################
# Step 2d: Store architecture pattern 4:
# Use messy global vars?
#############################################################

export const target = writable({
    name: 'cow',
    hp: 100,
});

export const ammo = writable([
    {
        type: 'armourPiercing',
        damage: 20,
    },
    {
        type: 'explosive',
        damage: 50,
    },
    {
        type: 'flash',
        damage: 1,
    }
]);

keyboardListener.subscribe(() => {

    let firstAmmo; // "Global" var
    ammo.set(currentAmmoValue => {
        const newAmmo = JSON.parse(JSON.stringify(currentAmmoValue));
        firstAmmo = newAmmo.pop();
        return newAmmo;
    });
    const ammoDamage = firstAmmo.damage;

    // If we have ammo, get the first ammo and reduce the cows HP.
    target.set(currentTargetValue => ({
        ...currentTargetValue,
        hp: currentTargetValue.hp - ammoDamage;
    }));
});
我想这很管用,但感觉很粗糙

所以你看,我很难为更大的应用商店架构找到一个好的模式。当然,这实际上是一个相对简单的应用程序——一个真实世界的应用程序当然要复杂得多


所以我想知道,在苗条地区,管理大型、相互关联的门店是否有既定的模式?

您尝试过衍生门店吗?嗯……派生存储组合存储值以生成新的输出值,但我真的想检查各种存储值以推断是否应该调用存储更新,以及在更新中使用什么参数。