Навигация SvelteKit задерживается из-за ожидания

У меня есть компонент, который асинхронно загружает некоторые данные и отображает их. Существуют также способы перехода на разные страницы этого компонента. Однако навигация происходит только после того, как все запросы #await будут обработаны. Я бы хотел перейти сразу после того, как пользователь нажмет на ссылку, а не ждать загрузки всех данных старой страницы. Есть ли способ сделать это?

Примерное описание того, что я делаю:

<script lang = "ts">
  import { goto } from '$app/navigation';

  let slowRequest = getSlowData();
</script>

<div class = "flex flex-col">
  {#await slowRequest}
    Loading...
  {:then result}
    result
  {/await}
  <button onclick = {() => goto("/some/other/page")}>
    Navigate
  </button>
</div>

Когда я нажимаю кнопку, мне приходится ждать разрешения запроса, прежде чем меня перенаправят. Есть ли возможность напрямую перейти на новую страницу, не дожидаясь ответа?


56
2

Ответы:

Можете ли вы указать, какую версию svelte вы используете? Я установил эту песочницу кода с помощью svelte v4.2.7, и навигация внутри приложения происходит мгновенно, независимо от состояния ожидания обещания.

Возможно, проблема заключается в другой части приложения. Вы можете отредактировать свой вопрос, включив в него эти части.

Кроме того, можно прервать запрос с помощью Контроллера прерывания, а затем перейти к другому маршруту, что должно решить проблему.


Решено

Для получения данных вам следует использовать функцию onMount. Не используйте await напрямую за пределами тегов script. Таким образом, ваш пользовательский интерфейс не будет заблокирован, и вы сможете перемещаться по нему, не дожидаясь завершения fetchData().

import { onMount } from 'svelte';

let slowRequest;

onMount(() => {
    fetchData();
});

async function fetchData(categoryId?: string) {
    slowRequest = await getSlowData(val);
}

ОБНОВЛЕНИЕ: ОТВЕТ НА ВОПРОС В РАЗДЕЛЕ КОММЕНТАРИЙ.

Если я правильно вас понял, вы хотите получить эти данные на основе другой переменной, которую вы выбираете из тега select-option html. Если вы это имели в виду, попробуйте следующее:

// Inside the script tag
function onChange(e) {
    const selectedCategoryId = e.target.value;
    fetchData(selectedCategoryId);
}

// Put this after the end of script tag.
<select on:change = {onChange}>
    <option value = {undefined}>Select an item</option>
    <option value = "id_1">Category 1</option>
    <option value = "id_2">Category 2</option>
    <option value = "id_3"> Category 3</option>
</select>

Обратите внимание, что я изменил функцию fetchData(categoryId?: string), чтобы она принимала необязательную переменную, чтобы getSlowData(categoryId?: string) {...} API можно было вызывать со значением или без него. т. е. если присутствует CategoryId, извлеките данные, специфичные для категории, в противном случае просто загрузите случайные данные.