JS-如果某件事比x花费更长的时间,那么就做点

时间:2019-02-12 10:18:24

标签: javascript typescript

如果某个动作(数据加载)所花费的时间超过某个特定时间,是否可以做些什么?

例如,在页面上有一些加载视觉元素的情况下,以防数据加载花费比平常更多的时间。 99%的负载是立即加载的,因此此元素只是FLASH,这很烦人。

是否可以执行以下操作:如果加载时间超过一秒钟=> show loader?

谢谢

2 个答案:

答案 0 :(得分:1)

是的,通过将范围足够大的变量和超时结合使用。

一些伪代码来说明这一点:

var showLoader = true;

myAjaxCall({
    'onSuccess': function() {
        showLoader = false;
    }
});

window.setTimeout(function() {
    if(showLoader) {
        // Show loader here
    }
}, 1000); // 1000 milliseconds = 1 second

应该注意,这是假设您的ajax是异步的。

答案 1 :(得分:0)

此处需要两个可配置的输入,在显示加载程序之前等待的时间(延迟),还需要最短持续时间,以便加载程序避免任何闪烁。

如果将延迟设置为1s,但是数据在1.1s之后到达,那么您将仅向加载器显示100ms,因此您将获得闪存,因此最小持续时间也很重要。

这是使用setTimeout的示例实现。您可以配置delayminDuration以获得所需的行为。

必须调用loadingAnimation()函数以开始动画处理。它返回一个stopAnimation()函数,异步操作完成后必须调用该函数。在这里,伪造的异步函数将这个stopAnimation()函数作为参数在setTimeout中调用。

const loader = document.querySelector('#loader');
const status = document.querySelector('#status');

const hideLoader = () => loader.style.display = 'none';
const showLoader = () => loader.style.display = 'block';

function loadingAnimation(delay = 500, minDuration = 1000) {
  let minDurationDone = false;
  let asyncActionDone = false;
  
  setTimeout(() => {
    if (!asyncActionDone) {
      showLoader();
      setTimeout(() => {
        minDurationDone = true;
        if (asyncActionDone) {
          hideLoader();
        }
      }, minDuration);
    }
  }, delay);
  
  const stopAnimation = () => {
    asyncActionDone = true;
    if (minDurationDone) {
      hideLoader();
    }
  };
  
  return stopAnimation;
}

function fakeAsyncAction(doneCallback, delay) {
  status.innerHTML = 'Started';
  setTimeout(() => {
    status.innerHTML = 'Done';
    doneCallback();
  }, delay);
}

function trigger(delay) {
  const stopAnimation = loadingAnimation();
  fakeAsyncAction(stopAnimation, delay);
}

hideLoader();
button {
  display: block;
  margin-bottom: 10px;
}

#loader {
  border: 5px solid #eee;
  border-top: 5px solid #3ad;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
<button onclick="trigger(300)">Trigger super short async action (300ms)</button>
<button onclick="trigger(700)">Trigger short async action (700ms)</button>
<button onclick="trigger(1500)">Trigger long async action (1500ms)</button>
<p>Async action status: <span id="status"></span></p>
<div id="loader"></div>