我有如下函数,如果我调用我的函数 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请求。
答案 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>