Могу ли я просто позволить функции предварительной загрузки Sapper просто ждать обещания без необходимости возвращать результат этого обещания?
Я понимаю, что есть preload()
функционировать в <script context="module">
и что все, что возвращает эта функция, передается компоненту как внешнее свойство, если вы написали export let whatever
в вашем компоненте.
Теперь я использую firestore вместе с rxfire, как на стороне сервера, так и на стороне клиента. Так что я могу просто сделатьimport { posts } from '../store'
а потом posts
буквально будет магазином, который будет постоянно обновляться всякий раз, когда получает новые снимки из firestore firebase.
В учебнике Svelte я заметил, что любая переменная, которую вы объявляете в<script context="module">
также будет доступен для вашего шаблона html, как если бы вы объявили его в обычном <script>
тег.
Итак мой ход мысли, я на самом деле не нуженpreload()
функция для возврата любых свойств, которые нужно добавить в мой компонент. Посколькуposts
переменная уже доступна для html-шаблона. Единственное, что мне действительно нужно сделать вpreload()
убедиться, что он ждет, пока не будет получен первый снимок данных из firestore. Это выглядело бы примерно так:
<script context="module">
import { posts } from '../store'
import { first } from 'rxjs/operators'
export async function preload() {
const result = await posts.pipe(first()).toPromise()
console.log(result) // this is just here to check if the results did indeed arrive
}
</script>
<h1>Recent posts</h1>
<ul>
{#each $posts as post}
<li>
<a href="/blog/{post.slug}" rel="prefetch">
{post.title}
</a>
</li>
{/each}
</ul>
Когда я запускаю этот код, я вижу в своем терминале, что данные сообщений действительно правильно распечатаны из console.log
, так что я знаю, что данные прибыли. Но по какой-то причине я не понимаю, это не работает, потому что шаблон все еще заканчивается хранилищем, в котором еще нет первого снимка данных. Таким образом, HTML-код SSR, который сервер отправляет в браузер, заканчивается пустым списком.
Я подумал, может быть, дело в том, что это хранилище, а не необработанные данные. Поэтому я упростил свой код, чтобы увидеть, не в этом ли проблема.
<script context="module">
import { wait } from '../utils'
import { writable } from 'svelte/store'
const blabla = writable('first value')
export async function preload() {
await wait(1000) // simulate a delay, like we would have when retrieving data from firestore
blabla.set('second value')
}
</script>
<h1>{$blabla}</h1>
Тогда html-код SSR действительно содержит текстsecond value
. Так что я не знаю, в чем проблема.
Кто-нибудь знает, что дает?
1 ответ
В конце концов, я смог исправить это, заменив rxjs и rxfire своим собственным кодом, который обертывает живые снимки firestore в svelte store. Так что должна быть просто какая-то странная несовместимость rxjs, которая все испортила.