gpt4 book ai didi

javascript - Svelte 中的每个异步

转载 作者:行者123 更新时间:2023-12-05 04:39:09 27 4
gpt4 key购买 nike

我尝试在 svelte 中使用异步 #each 循环,发现它无论如何都会同步运行,使用这样的异步等待函数:

{#each items as item (item.id)}
{#await render(item) then source}
<Canvas {source} />
{:catch}
<p>error</p>
{/await}
{/each}

发现在 svelte 中无法使用异步组件,因为 onmount 不能像这样异步使用:

{#each items as item (item.id)}
<Canvas {item} />
{/each}

这个问题有解决办法吗?

最佳答案

根据您的评论,听起来您在使用异步更新数组中的元素时遇到了问题。下面是一个使用异步函数在 onMount 中初始化的示例,然后使用 immutable 标志重新渲染以仅更新那些已更改的元素。此示例将所有 promise 处理放在脚本中而不是放在 jsx 中。

REPL

// App.svelte
<svelte:options immutable={false} />

<script>
import Item from "./Item.svelte";
import { onMount } from "svelte";

let array;

const sleep = async (ms) => await new Promise((r) => setTimeout(r, ms));

async function render(id) {
await sleep(800);
array = array.map((item) => {
if (item.id === id) {
return {
...item,
render: item.render + 1,
};
}
return item;
});
}

onMount(() => {
async function init() {
array = await Promise.all(
[...Array.from({ length: 5 }).keys()].map((i) =>
Promise.resolve({
id: i + 1,
name: `item_${i + 1}`,
render: 0,
})
)
);
}

init();

return () => console.log("destroyed");
});
</script>

{#if array && array.length}
{#each array as item (item.id)}
<Item {item} on:click={() => render(item.id)} />
{/each}
{/if}
// ./Item.svelte
<svelte:options immutable={true} />

<script>
import { afterUpdate } from "svelte";

export let item;
</script>

<div>
<p>
{item.name} [render: {item.render}]
</p>
<button on:click>render</button>
</div>

但您也可以合并一个 {#await} block 来处理 jsx 中的一系列 promise 。 (它使用与上面相同的 Item 组件)

REPL

// App.svelte
<svelte:options immutable={false} />

<script>
import Item from "./Item.svelte";
import { onMount } from "svelte";

let array;

async function render(id) {
array = await Promise.all(
array.map(async (promiseItem) => {
if (promiseItem.id === id) {
const _item = await promiseItem.item;
return {
id: promiseItem.id,
item: new Promise((r) =>
setTimeout(() => r({ ..._item, render: _item.render + 1,}), 800)
),
};
}
return promiseItem;
})
);
}

onMount(() => {
async function init() {
array = [...Array.from({ length: 5 }).keys()].map((i) => ({
id: i,
item: Promise.resolve({
id: i + 1,
name: `item_${i + 1}`,
render: 0,
}),
}));
}

init();

return () => console.log("destroyed");
});
</script>

{#if array && array.length}
{#each array as { id, item: promise } (id)}
{#await promise}
<p>...rendering</p>
{:then item}
<Item {item} on:click={() => render(item.id)} />
{/await}
{/each}
{/if}

原始答案

您还没有真正弄清楚什么不起作用。您可以onMount 中运行异步调用并在 {#await} block 中等待 promise 。

这是一个人为的 REPL构建一个 promise 数组,使用 Promise.all 来解决它们并将生成的 promise 分配给要呈现的变量。

<script>
import { onMount } from "svelte";

let promise;

async function render(i) {
return {
id: i + 1,
name: `item_${i + 1}`,
};
}

onMount(() => {
const array = [...Array.from({length: 5}).keys()];
promise = Promise.all(array.map((i) => render(i)));

return () => console.log("destroyed");
});
</script>

{#await promise}
<p>...rendering</p>
{:then array}
{#if array && array.length}
{#each array as item (item.id)}
<p>
{item.name}
</p>
{/each}
{/if}
{:catch error}
<p>oh dear.</p>
{/await}

关于javascript - Svelte 中的每个异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70468246/

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