繁体   English   中英

如何从 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 中时,该数字会在单击按钮时立即生成。 这是预期的并且确实应该发生。

调用异步函数以便仅在单击按钮时获取 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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM