如何从 svelte 在 javascript 中单击按钮时调用异步函数?
How to call an async function on button click in javascript from svelte?
以下示例来自svelte官方文档
<script>
async function getRandomNumber() {
const res = await fetch(`tutorial/random-number`);
const text = await res.text();
if (res.ok) {
return text;
} else {
throw new Error(text);
}
}
let promise = getRandomNumber(); -------------- How does this work?
function handleClick() {
promise = getRandomNumber();
}
</script>
<button on:click={handleClick}>
generate random number
</button>
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
我的问题是,当我们像上面那样将 'promise' 分配给函数 'call' 时,它应该立即调用该函数。在 svelte repl 中,这不会发生,随机数仅在单击按钮时生成。但是,当我修改代码以从简单的快速服务器获取 json 时,我什至不需要单击按钮 - 在应用程序启动时调用服务器。 (这是你所期望的)。发生了什么魔法?
虽然可能不重要,但这是我试过的代码。
<script>
async function getNotes() {
const res = await fetch('http://localhost:3001/api/notes')
const json = await res.json()
if(res.ok) {
return json;
} else {
throw new Error(res)
}
}
let promise = getNotes();
function onClickGetNotes() {
promise = getNotes();
}
</script>
<div class="grid-item-container card">
<button on:click={onClickGetNotes}> Get Notes </button>
{#await promise}
.. Loading notes
{:then notes}
{#each notes as note (note.id)}
<div class="grid-item-container card">
<p class="grid-item"> ID is {note.id} </p>
<p class="grid-item"> Content is {note.content} </p>
<lable class="grid-item" for="important"> Important
<input class="grid-item" type="checkbox" id="important" checked={note.important}>
</lable>
</div>
{/each}
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
</div>
调用异步函数以便仅在单击按钮时获取 json 的最佳方法是什么?
当我将您的代码按原样复制到 REPL 中时,数字会立即生成并在单击按钮时生成。这是意料之中的事情,确实应该发生。
What is the best way to call the async function so that the json is only fetched on button click?
好吧,在你需要它之前不要调用它。如果不是您想要的,则不在组件创建时。你可以简单地拥有:
let promise
这将显示“号码未定义”。
如果您只想在发生某些事情时显示文本,您可以将其包装成 if
:
<button on:click={handleClick}>
generate random number
</button>
<button on:click={() => { promise = null }}>
reset
</button>
{#if promise != null}
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
{/if}
或者如果你愿意,你可以给你的变量一个非 Promise 初始值:
let promise = 0
如果你愿意,甚至是一个承诺:
let promise = Promise.resolve(42)
只是添加这个供我参考。这就是我在 Rix 回答之前所做的事情。
<script>
let notes = []
async function getNotes() {
const res = await fetch('http://localhost:3001/api/notes')
const json = await res.json()
notes = json
console.log('notes', notes)
}
async function onClickGetNotes() {
await getNotes()
}
</script>
<div class="grid-item-container card">
<h4 class="grid-item"> Find the best</h4>
<label class="grid-item" for="site-search">Suburb or Postcode</label>
<input class="grid-item" type="search" id="site-search" name="q">
<button on:click={onClickGetNotes}> Get Notes </button>
{#each notes as note (note.id)}
<div class="grid-item-container card">
<p class="grid-item"> ID is {note.id} </p>
<p class="grid-item"> Content is {note.content} </p>
<lable class="grid-item" for="important"> Important
<input class="grid-item" type="checkbox" id="important" checked={note.important}>
</lable>
</div>
{/each}
</div>
以下示例来自svelte官方文档
<script>
async function getRandomNumber() {
const res = await fetch(`tutorial/random-number`);
const text = await res.text();
if (res.ok) {
return text;
} else {
throw new Error(text);
}
}
let promise = getRandomNumber(); -------------- How does this work?
function handleClick() {
promise = getRandomNumber();
}
</script>
<button on:click={handleClick}>
generate random number
</button>
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
我的问题是,当我们像上面那样将 'promise' 分配给函数 'call' 时,它应该立即调用该函数。在 svelte repl 中,这不会发生,随机数仅在单击按钮时生成。但是,当我修改代码以从简单的快速服务器获取 json 时,我什至不需要单击按钮 - 在应用程序启动时调用服务器。 (这是你所期望的)。发生了什么魔法?
虽然可能不重要,但这是我试过的代码。
<script>
async function getNotes() {
const res = await fetch('http://localhost:3001/api/notes')
const json = await res.json()
if(res.ok) {
return json;
} else {
throw new Error(res)
}
}
let promise = getNotes();
function onClickGetNotes() {
promise = getNotes();
}
</script>
<div class="grid-item-container card">
<button on:click={onClickGetNotes}> Get Notes </button>
{#await promise}
.. Loading notes
{:then notes}
{#each notes as note (note.id)}
<div class="grid-item-container card">
<p class="grid-item"> ID is {note.id} </p>
<p class="grid-item"> Content is {note.content} </p>
<lable class="grid-item" for="important"> Important
<input class="grid-item" type="checkbox" id="important" checked={note.important}>
</lable>
</div>
{/each}
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
</div>
调用异步函数以便仅在单击按钮时获取 json 的最佳方法是什么?
当我将您的代码按原样复制到 REPL 中时,数字会立即生成并在单击按钮时生成。这是意料之中的事情,确实应该发生。
What is the best way to call the async function so that the json is only fetched on button click?
好吧,在你需要它之前不要调用它。如果不是您想要的,则不在组件创建时。你可以简单地拥有:
let promise
这将显示“号码未定义”。
如果您只想在发生某些事情时显示文本,您可以将其包装成 if
:
<button on:click={handleClick}>
generate random number
</button>
<button on:click={() => { promise = null }}>
reset
</button>
{#if promise != null}
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
{/if}
或者如果你愿意,你可以给你的变量一个非 Promise 初始值:
let promise = 0
如果你愿意,甚至是一个承诺:
let promise = Promise.resolve(42)
只是添加这个供我参考。这就是我在 Rix 回答之前所做的事情。
<script>
let notes = []
async function getNotes() {
const res = await fetch('http://localhost:3001/api/notes')
const json = await res.json()
notes = json
console.log('notes', notes)
}
async function onClickGetNotes() {
await getNotes()
}
</script>
<div class="grid-item-container card">
<h4 class="grid-item"> Find the best</h4>
<label class="grid-item" for="site-search">Suburb or Postcode</label>
<input class="grid-item" type="search" id="site-search" name="q">
<button on:click={onClickGetNotes}> Get Notes </button>
{#each notes as note (note.id)}
<div class="grid-item-container card">
<p class="grid-item"> ID is {note.id} </p>
<p class="grid-item"> Content is {note.content} </p>
<lable class="grid-item" for="important"> Important
<input class="grid-item" type="checkbox" id="important" checked={note.important}>
</lable>
</div>
{/each}
</div>