【问题标题】:How to show loading icon till await finishes如何在等待完成之前显示加载图标
【发布时间】:2020-03-08 06:06:16
【问题描述】:

我有一个带有 await fetch 的异步函数。 我想向用户显示一个加载图标,直到等待完成,然后显示下一个 div。

                let getOTP = await fetch(url, {
                    method: 'POST',
                    headers: {
                        "Content-Type": "text/plain"     
                    },
                    body: JSON.stringify({
                        "Number": mobileNumber
                    })
                });

                let data = await getOTP.json();
                let errorCode = data.errorCode;
                if (errorCode == 0) {// show next div}

我尝试使用 setTimeout(function (){},5000) 函数设置为 5 秒(或更多),但有时需要更长的时间才能收到回复。那么,如何在等待完成之前显示加载图标?

【问题讨论】:

  • 你应该从后端收到一个事件来停止收费
  • 你把 setTimeout 调用放在哪里?请在其他代码的上下文中显示它

标签: javascript async-await loading


【解决方案1】:

在 fetch 之前只显示加载器,在await 之后将其删除。

const fetchButton = document.querySelector('#fetchButton')
const loader = document.querySelector('#loader')
const content = document.querySelector('#content')

function fetchData() {
  // Here should be your api call, I`m using setTimeout here just for async example
  return new Promise(resolve => setTimeout(resolve, 2000, 'my content'))
}

fetchButton.onclick = async function () {
  content.innerHTML = ''

  // Your loader styling, mine is just text that I display and hide
  loader.style.display = 'block'
  const nextContent = await fetchData()
  loader.style.display = 'none'

  content.innerHTML = nextContent
}
<button id="fetchButton">Fetch</button>
<div id="loader" style="display: none">Loading...</div>
<div id="content"></div>

【讨论】:

  • 你应该使用 try-finally 来确保在加载出现问题时加载图标也被隐藏
  • @NineBerry 绝对是,如果您使用的是真正的 fetch api 或 axios 可以抛出它是强制性的处理错误。但在我的示例中,setTimeout 肯定不会抛出 :) 尽管如此,如果在 fetchData 函数中处理错误并且不会影响加载切换功能,则不需要 finally 大小写。
【解决方案2】:

只需将隐藏图标的代码放在调用await 的行之后。使用try / finally 确保在异步调用中出现问题时也执行代码。

您可以将此机制封装在类似WithIcon 函数的函数中,如下所示,以便在不同的地方重用它。

// Test function
async function test()
{
    await WithIcon(timeout(3000));
    testAfterAction();
}

function testAfterAction()
{
    var elem = document.createElement('div');
    elem.innerText = "Some text";
    document.body.appendChild(elem);	
}

// Use setTimeout to symulate some asynchronous i/o operation
function timeout(ms) 
{
    return new Promise(resolve => setTimeout(resolve, ms));
}


// While awaiting the promise, show a wait icon
async function WithIcon(promise)
{
    ShowAwaiting();
    try
    {
        await promise;
    }
    finally
    {
        HideAwaiting();
    }
}

// To only hide the icon when every ShowAwaiting call was met with a HideAwaiting call
var globalAwaitingCounter = 0;

// Show wait icon
function ShowAwaiting()
{
    if(globalAwaitingCounter <= 0)
    {
        document.getElementById("awaiting").style.display = "inline";
        globalAwaitingCounter = 1;
    }
    else
    {
        globalAwaitingCounter++;
    }
}

// Hide wait icon
function HideAwaiting()
{
    if(globalAwaitingCounter <= 1)
    {
        document.getElementById("awaiting").style.display = "none";
        globalAwaitingCounter = 0;
    }
    else
    {
        globalAwaitingCounter--;
    }
}
<html>
<body>
  <button type="button" onclick="test();">Test</button>
  <span id="awaiting" style="display:none">Awaiting....</span>
</body>
</html>

【讨论】:

    【解决方案3】:

    在代码开头开始加载图像,并在没有错误并且代码进入(errorCode == 0) 条件时停止。

                <-- START loading Here -->
                let getOTP = await fetch(url, {
                    method: 'POST',
                    headers: {
                        "Content-Type": "text/plain"     
                    },
                    body: JSON.stringify({
                        "Number": mobileNumber
                    })
                });
    
                let data = await getOTP.json();
                let errorCode = data.errorCode;
                if (errorCode == 0) {
                   <-- STOP loading Here -->
                }else{
                   <-- STOP loading Here on error -->
                }
    

    【讨论】:

    • 如果加载失败,为什么不想隐藏加载图标?
    • 我已经添加了代码,但这不是拒绝投票的正确方法。您只能发表评论。可以看到,OP没有提供完整的代码,所以我们无法想象代码中应该遵循的步骤。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多