Svelte:如何处理组件中自定义可写存储的异步初始化承诺?

Jar*_*ler 6 svelte svelte-component svelte-store svelte-3

我有几个 Svelte 组件和一个自定义可写存储。存储有一个init函数,async它用一些 REST API 的数据库表的数据填充存储的值。我的组件都必须使用自动订阅来订阅该商店。订阅时,init必须调用。总体想法是在数据库上实现 CRUD 操作,在存储上实现 CRUD 操作(有助于显示存储的值,数据库的表,具有反应性)。

init原样async,因此返回一个承诺,我需要await在我的组件中使用它。但由于我使用自动订阅(通过在商店名称前加上前缀$),我该怎么做?

例如:(App.svelte组件):

<script>
    import { restaurant_store } from './Restaurant.js'
    export let name
</script>

<main>
    
    <!--- I need to handle the promise and rejection here -->
    {#each $restaurant_store as restaurant}
        <li>
            {restaurant.name}
        </li>
    {/each}
    

</main>
Run Code Online (Sandbox Code Playgroud)

Restaurant.js(商店):

import { writable } from 'svelte/store'

export function createRestaurantsStore() {
    const { subscribe, update } = writable({ collection: [] })

    return {
        subscribe,

        init: async () => {
            const response = await fetch('http://localhost:1337/restaurants')

            if(response.ok) {
                const json_response = await response.json()
                set({ collection: json_response })
                return json_response
            }

            throw Error(response.statusText)
        },

        insert: async (restaurant) => {
            const response = await fetch('http://localhost:1337/restaurants', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(restaurant)
            })

            if(response.ok) {
                const json_response = await response.json()
                update(store_state => store_state.collection.push(json_response))
                return json_response
            }

            throw Error(response.statusText)
        },

        update: async (restaurant, id) => {
            const response = await fetch('http://localhost:1337/restaurants/' + id, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(restaurant)
            })

            if(response.ok) {
                const json_response = await response.json()
                update(store_state => {
                    const current_id = store_state.collection.findIndex(e => e.id === id)
                    store_state.collection.splice(current_id, 1, json_response)
                })
                return json_response
            }

            throw Error(response.statusText)

        }

    }
}

export const restaurant_store = createRestaurantsStore()
Run Code Online (Sandbox Code Playgroud)

joh*_*pin 9

Svelte 提供了一个内置机制来处理模板中 Promise 的可能状态,因此同样的情况可能如下所示:

<main>
    {#await restaurant_store.init()}
        <p>waiting for the promise to resolve...</p>
    {:then}
      {#each $restaurant_store as restaurant}
        <li>
          {restaurant.name}
        </li>
      {/each}
    {:catch error}
        <p>Something went wrong: {error.message}</p>
    {/await}
</main>
Run Code Online (Sandbox Code Playgroud)

查看REPL以获得实例。

  • REPL 实际上并没有起作用。还应该注意的是,如果您在 $restaurant_store 上设置/更新,在该示例中,#await 块的内容将不会再次显示。这是一个 REPL,每当您更新商店时都会重新显示 #await 块的内容 https://svelte.dev/repl/d78d7327830442ab87cc47bcee1033f9?version=3.43.1 (3认同)