【问题标题】:How to call an async function on button click in javascript from svelte?如何在 svelte 的 javascript 中单击按钮时调用异步函数?
【发布时间】:2020-11-17 12:53:34
【问题描述】:

以下示例来自 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}

我的问题是,当我们如上所述将“承诺”分配给函数“调用”时,它应该立即调用该函数。在 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?

【问题讨论】:

  • “调用异步函数的最佳方法是什么,以便仅在单击按钮时获取 json?”不要在点击事件处理程序之外调用getNotes()...
  • 谢谢,但为什么我不能直接从 on:click 调用 getNotes()?点赞:click = {getNotes}
  • 我不了解 Svelte,所以无法回答这个问题。
  • Svelte 应该只是一个编译器,所以任何 js 逻辑都应该适用于 svelte。这就是我担心的原因!

标签: javascript async-await fetch svelte


【解决方案1】:

当我将您的代码按原样复制到 REPL 中时,该数字会立即生成并在按钮单击时生成。这是预期的,并且确实应该发生。

调用异步函数的最佳方法是什么,以便仅在单击按钮时获取 json?

好吧,在你需要它之​​前不要调用它。不在组件创建时,如果它不是您想要的。您可以简单地拥有:

    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)

【讨论】:

  • 非常感谢!我不知道我是如何错过函数调用最初发生的(我现在相信这是故意的)。爱苗条!
【解决方案2】:

只是添加这个供我参考。这就是我在 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>

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 2023-03-31
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 2020-12-23
    相关资源
    最近更新 更多