我有一個用例,我在20秒後執行setTimeout函數,但我希望在前端的套接字連接在20秒之前返回某些內容時執行該函數。在這種情況下,我不希望它在20秒後運行。我怎麼能做到這一點。如果套接字已收到某些請求,則在執行setTimeout函數之前執行setTimeout函數
回答
這裏最簡單的方案是隻是把你的代碼中,你與setTimeout()
使用,如果計時器仍在運行,則取消計時器和直接調用該函數的函數:
function doSomeTask() {
// code here for your task
}
// schedule task to run in 20 seconds
// remember timer handle so we know it's running
let timer = setTimeout(() => {
timer = null;
doSomeTask();
}, 20*1000);
// elsewhere in your code where you want to call your function
// earlier than the timer (if it hasn't already been called)
if (timer) {
clearTimeout(timer);
timer = null;
doSomeTask();
}
承諾可以在這裏提供一些好處,因爲他們已經確保給定的承諾只能解決或拒絕一次,並可以在這裏利用。爲了優雅地使用它們,我可能會創建一個小狀態對象,使它非常易於使用。
function delayExecute(fn, t) {
let obj = {state: "timer"};
let p = new Promise((resolve, reject) => {
obj.runNow = resolve;
obj.cancel = reject;
setTimeout(resolve, t);
}).catch(err => {
obj.state = "err";
throw err;
}).then(() => {
fn();
obj.state = "done";
});
return obj;
}
function doSomeTask() {
// code here for your task
}
let task = delayExecute(doSomeTask, 20*1000);
// then some time later, to run it sooner (if it hasn't already run)
// calling the .runNow() method after the function has already run will do nothing
task.runNow();
這個相同的接口也可以沒有承諾建立。我只是想我會展示如何利用一些承諾的單向狀態轉換來實現此目的。
絕對是最直接的方法。在我看來,承諾對於這個特殊問題是過分的。 +1 –
@PatrickRoberts - 我添加了一個基於承諾的實現,僅僅是爲了展示如何幹淨地完成它。這裏肯定不需要承諾,但他們做了一些有用的事情,可以在這裏使用。 – jfriend00
不錯的更新,但是你的'cancel()'實際上並沒有取消:P哦,等等,我去了。這是一種奇怪的做法,我本可以做一些有點不同的事情,但確實有效。 –
你有幾個選擇來做到這一點。由於您沒有包含任何關於如何管理併發的代碼或信息,因此我會向您展示一種使用承諾似乎合理的方式。
let resolve;
let promise = new Promise(res => resolve = res);
// function to call after max 2s or after response
let fn =() => {
console.log(process.uptime(), 'Function called');
};
// the timeout:
setTimeout(resolve, 1000);
// the fake response handler:
setTimeout(() => {
console.log(process.uptime(), 'Request returned');
resolve();
}, 2000 * Math.random());
promise.then(fn);
then
處理程序將只運行一次。執行此程序多次,您會看到該函數在假響應處理程序被調用後立即被調用(如果在1秒超時觸發之前調用該函數),或者如果超時爲第一個,則立即在超時之後調用該函數。
- 1. setTimeout不執行傳遞函數
- 2. jQuery setTimeout不停止函數執行
- 3. setTimeout()不執行
- 4. Javascript Promise.all()在函數完成之前執行,node.js請求庫
- 5. setTimeout沒有執行
- 6. 如何在JavaScript中使用setTimeout()來執行已聲明的函數?
- 7. 在函數上執行setTimeout的問題 - 將此函數作爲參數傳遞
- 8. 如果數組已設置,請執行某些操作?
- 9. 在運行某個函數之前估計執行時間
- 10. cherrypy,在每個請求之前自動執行某些操作
- 11. 調用setTimeout函數之後的函數
- 12. setTimeout()/ setInterval()將不會執行。 **我傳遞函數對象 - 不執行功能
- 13. 在函數結束前執行函數
- 14. anonymous setTimeout函數
- 15. Javascript - setTimeout函數
- 16. 在DidSelectAtRow函數之前執行的Segue正在執行
- 17. JavaScript setTimeout函數沒有按預期執行
- 18. setTimeout循環中有3個函數要在前一個完成後執行
- 19. 執行SetTimeout或$超時只有在某些動作
- 20. 在請求在RestKit中完成之前和之後執行函數
- 21. 使用express.js在接收到一個http請求後執行一個函數?
- 22. 的setTimeout執行多次
- 23. 立即執行setTimeout回調
- 24. Render()之前的ASP.NET執行函數
- 25. Sys.sleep()之前沒有執行的函數()
- 26. 如何在某些圖像上使用setTimeout函數?
- 27. 如何在使用remote_form_for啓動AJAX請求之前執行JS函數
- 28. jQuery函數的setTimeout
- 29. 的Javascript setTimeout函數
- 30. 爲什麼不執行setInterval執行之前定義的函數?
請給我們看一些代碼,以便我們找出問題所在,並提出建議或幫助您解決問題。 –