只调用一次函数

时间:2021-04-08 17:34:11

标签: javascript

我有如下函数,如果我调用我的函数 refreshPrice(),它会启动一个 ajax 请求,并在 10 秒后再次调用该函数刷新价格。

 function refreshPrice() {

     var url = "example.com/refresh.php";
     $.get(url, function(data) {

         pricetimeout = setTimeout(function() {
             refreshPrice()
         }, 10000);

     })

 }

问题是我再次调用 refreshPrice() 以立即调用 ajax.. 有多个 refreshPrice() 函数被调用。

clearTimeout(pricetimeout); 

实际需要的是 pricetimeout 应该只在第一次调用,它应该每 10 秒运行一次,我不想要 setinterval(如果页面在后台使用 seinterval,我会遇到问题)

从第二次开始,只应该完成没有超时的ajax请求。

4 个答案:

答案 0 :(得分:1)

您可以通过标志来消除第二次超时

     function refreshPrice(flag) {

       var url = "example.com/refresh.php";
       $.get(url, function(data) {
         if(flag){
           pricetimeout = setTimeout(function() {
            refreshPrice(false)
           }, 10000);
         } else {
           refreshPrice(false);
         }
       })

     }

答案 1 :(得分:1)

我使用 jQuery 已经很长时间了,但是 the docs 向我保证 $.get 的返回值是 Promise 兼容的,这意味着您不需要提供回调并且可以await其结果。

这意味着您应该能够使用 async/await 来创建一个 async 循环,如下所示(未经测试):

const delay = (delayMs) => new Promise((resolve) => setTimeout(() => resolve(), delayMs));

async function refreshPrice() {
   var url = "example.com/refresh.php";
   while(true){
      const data = await $.get(url);
      // do something with data
      await delay(10000);
   }
}

refreshPrice(); // fire-and-forget this unawaited promise

这样做的好处是超时等待发生在 网络调用之间,因此如果网络很慢,事情就不会开始重叠。

答案 2 :(得分:1)

您可以尝试使用 async 函数,如下所示。

 async function refreshPrice() {
   var url = "example.com/refresh.php";
   $.get(url, yourCallback);
   
  //wait for 10s before calling refresh price again
  await new Promise(resolve => setTimeout(resolve, 10 * 1000));
  refreshPrice();
 }

这会起作用,而不是告诉浏览器在收到响应后调用 refreshPrice 函数。因此,如果您在 1 秒后收到响应,您的函数将在 1 秒后被调用。

答案 3 :(得分:1)

我还没有测试过这个,但这应该给你一个起点(这真的非常迅速地组合在一起)

var myRefresher = myRefresher || {
  url: "example.com/refresh.php",
  waitTime: 10000,
  shouldStop: false,
  handleRefresh: function(data, textStatus, jqXHR) {
    setTimeout(function() {
      if (!myRefresher.shouldStop) {
        $(document).trigger('dopricerefresh');
      }
    }, myRefresher.waitTime);
  },
  doNewRefresh: function() {
    myRefresher.refreshPrice().then(myRefresher.handleRefresh);
  },
  refreshPrice: function() {
    return $.ajax({
        url: someUrl,
        data: {},
        xhrFields: {
          withCredentials: true
        }
      })
      .done(function(data, textStatus, jqXHR) {
        console.log("success");
        // do what you need here
      })
      .fail(function(jqXHR, textStatus, errorThrown) {
        // handle your error
        myRefresher.shouldStop = false; //stop trying
      })
      // read doc for parameters
      // .always(function(data or jqXHR, textStatus, jqXHR or errorThrown) {
      // done and/or fail next thing
      // })
      // combines done/fail, see reference page
      .then(handleRefresh // gets passed data, textStatus, jqXHR 
        ,
        function(jqXHR, textStatus, errorThrown) {}) // fail in then
  }
};
// start the cycle
$(document)
  .on('dopricerefresh', myRefresher.handleRefresh)
  .trigger('dopricerefresh');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>