输入新起点时清除 javascript 计时器
Clearing a javascript timer when new starting point is input
是的,我是新来的,别担心让我听起来很蠢。 :) 这是一个用 Google 脚本编写的网络应用程序,它从 Google 表格中获取信息。
我采用了此处评论中的代码:Javascript timer to use multiple times in a page。当前代码如下。在这整个过程中,我 运行 有几个不同的计时器,它们每秒都减少 1 秒 - 太棒了。我的问题是因为第一个代码获取的 google sheet 的值每隔几分钟就会改变一次。我希望它从最近的数据开始倒计时,并使 "old" 计数器停止。通过阅读几个相关的线程,我认为我在某处需要另一个 clearInterval,但我不知道把它放在哪里。
Google Apps 获取 Google sheet 值并将它们放入变量中的脚本。 "getdata" 值是未来的日期,然后 "data" 是距离该日期还有多少秒:
function getfivecoins(){
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Live");
var getdata = livesheet.getRange("D42").getValue().getTime();
var now = new Date().getTime();
var data = (getdata-now)/1000; // how many seconds in the future this date is
return data;
}
function gettencoins(){
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Live");
var getdata = livesheet.getRange("D43").getValue().getTime();
var now = new Date().getTime();
var data = (getdata-now)/1000; // how many seconds in the future this date is
return data;
}
然后在 html 页:
<span id="timer1"></span>
<br>
<span id="timer2"></span>
<br>
在脚本标签内向下:
// 每 10 秒,从 google sheets 获取新值。如果值相同,倒计时应该继续正常进行(有几毫秒的差异,无论如何),但如果值已更改,则尝试让倒计时重新开始。如果更简单,清除所有倒计时然后重新开始应该会有相同的结果。
document.addEventListener('DOMContentLoaded', function(){
setInterval(function(){
google.script.run.withSuccessHandler(generatefivecoins).getfivecoins();
google.script.run.withSuccessHandler(generatetencoins).gettencoins();
}, 10000);
});
const clearStack = []; //Added
function generatefivecoins(result) {
clearStack.forEach(clearInterval); //Added
var timer = document.getElementById('timer1');
var t = new timerObject();
clearStack.push(t.startTimer(result, timer)); //Modified
}
function generatetencoins(result){
clearStack.forEach(clearInterval); //Added
var timer = document.getElementById("timer2");
var t = new timerObject();
clearStack.push(t.startTimer(result, timer)); //Modified
}
var timerObject = function(){
return this;
};
timerObject.prototype.startTimer = function(duration, display) {
var me = this,
timer = duration,
STYLETEST, hours, minutes, seconds, ENDSTYLETEST;
var intervalLoop = setInterval(() => { // modified this line
//fancy colours and formatting stuff goes here
display.innerHTML = STYLETEST + " " + hours + ":" + minutes + ":" + seconds + ENDSTYLETEST;
if (--timer < 0) {
clearInterval(intervalLoop);
}
}, 1000);
return intervalLoop; //Added
};
流量:
- 我们使用带有可变参数的单个函数,而不是多个函数。
coinBucket
持有可生成的不同硬币
- 从服务器端调用
generateCoins
后,我们使用 Map
to store timerObject
instance of class 。在下一次调用期间,我们使用相同的 timerObject 而不是创建一个新的。
code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('index');
}
const getCoins = coin => {
const map = { 5: 'D42', 10: 'D43', 20: 'D48', 60: 'D49', 90: 'D50' };//fivecoin range = D42 and so on
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Live');
var getdata = livesheet
.getRange(map[coin])
.getValue()
.getTime();
var now = new Date().getTime();
var data = getdata - now; // how many milliseconds in the future this date is
return data;
};
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<h1>Coins!!</h1>
<span id="timer1"></span>
<span id="timer2"></span>
<span id="timer3"></span>
<span id="timer4"></span>
<span id="timer5"></span>
</body>
<script>
const coinBucket = [5, 10, 20, 60, 90];//number of coin buckets
const GSR = (func, ...args) =>// google.script.run to promise
new Promise((resolve, reject) =>
google.script.run
.withSuccessHandler(resolve)
.withFailureHandler(reject)
[func](...args)
);
const clearStack = new Map();//map to store timerObjects
function generateCoins(result, i) {
const timer = clearStack.get(i) || new timerObject(i);
clearStack.set(i, timer);
timer.stopTimer();
timer.startTimer(result);
}
class timerObject {
constructor(id) {
this.elementId = 'timer' + (id + 1);
this.timerIds = [];
}
startTimer(duration) {
const display = document.getElementById(this.elementId);
this.timerIds.push(
setInterval(() => {
const hours = parseInt(duration / 1000 / 60 / 60, 10),
minutes = parseInt((duration / 1000 / 60) % 60, 10),
seconds = parseInt((duration / 1000) % 60, 10);
display.innerHTML = [hours, minutes, seconds]
.map((e) => ('0' + e).slice(-2))
.join(':');
duration = duration - 1000;
if (duration < 0) this.stopTimer();
}, 1000)
);
}
stopTimer() {
this.timerIds.forEach(clearInterval);
this.timerIds = [];
}
}
document.addEventListener('DOMContentLoaded', function () {
setInterval(function () {
Promise.all(
coinBucket.map((bucket) => GSR('getCoins', bucket))
).then((values) => values.forEach(generateCoins));
}, 10000);
});
</script>
</html>
是的,我是新来的,别担心让我听起来很蠢。 :) 这是一个用 Google 脚本编写的网络应用程序,它从 Google 表格中获取信息。
我采用了此处评论中的代码:Javascript timer to use multiple times in a page。当前代码如下。在这整个过程中,我 运行 有几个不同的计时器,它们每秒都减少 1 秒 - 太棒了。我的问题是因为第一个代码获取的 google sheet 的值每隔几分钟就会改变一次。我希望它从最近的数据开始倒计时,并使 "old" 计数器停止。通过阅读几个相关的线程,我认为我在某处需要另一个 clearInterval,但我不知道把它放在哪里。
Google Apps 获取 Google sheet 值并将它们放入变量中的脚本。 "getdata" 值是未来的日期,然后 "data" 是距离该日期还有多少秒:
function getfivecoins(){
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Live");
var getdata = livesheet.getRange("D42").getValue().getTime();
var now = new Date().getTime();
var data = (getdata-now)/1000; // how many seconds in the future this date is
return data;
}
function gettencoins(){
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Live");
var getdata = livesheet.getRange("D43").getValue().getTime();
var now = new Date().getTime();
var data = (getdata-now)/1000; // how many seconds in the future this date is
return data;
}
然后在 html 页:
<span id="timer1"></span>
<br>
<span id="timer2"></span>
<br>
在脚本标签内向下:
// 每 10 秒,从 google sheets 获取新值。如果值相同,倒计时应该继续正常进行(有几毫秒的差异,无论如何),但如果值已更改,则尝试让倒计时重新开始。如果更简单,清除所有倒计时然后重新开始应该会有相同的结果。
document.addEventListener('DOMContentLoaded', function(){
setInterval(function(){
google.script.run.withSuccessHandler(generatefivecoins).getfivecoins();
google.script.run.withSuccessHandler(generatetencoins).gettencoins();
}, 10000);
});
const clearStack = []; //Added
function generatefivecoins(result) {
clearStack.forEach(clearInterval); //Added
var timer = document.getElementById('timer1');
var t = new timerObject();
clearStack.push(t.startTimer(result, timer)); //Modified
}
function generatetencoins(result){
clearStack.forEach(clearInterval); //Added
var timer = document.getElementById("timer2");
var t = new timerObject();
clearStack.push(t.startTimer(result, timer)); //Modified
}
var timerObject = function(){
return this;
};
timerObject.prototype.startTimer = function(duration, display) {
var me = this,
timer = duration,
STYLETEST, hours, minutes, seconds, ENDSTYLETEST;
var intervalLoop = setInterval(() => { // modified this line
//fancy colours and formatting stuff goes here
display.innerHTML = STYLETEST + " " + hours + ":" + minutes + ":" + seconds + ENDSTYLETEST;
if (--timer < 0) {
clearInterval(intervalLoop);
}
}, 1000);
return intervalLoop; //Added
};
流量:
- 我们使用带有可变参数的单个函数,而不是多个函数。
coinBucket
持有可生成的不同硬币- 从服务器端调用
generateCoins
后,我们使用Map
to storetimerObject
instance of class 。在下一次调用期间,我们使用相同的 timerObject 而不是创建一个新的。
code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('index');
}
const getCoins = coin => {
const map = { 5: 'D42', 10: 'D43', 20: 'D48', 60: 'D49', 90: 'D50' };//fivecoin range = D42 and so on
var livesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Live');
var getdata = livesheet
.getRange(map[coin])
.getValue()
.getTime();
var now = new Date().getTime();
var data = getdata - now; // how many milliseconds in the future this date is
return data;
};
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<h1>Coins!!</h1>
<span id="timer1"></span>
<span id="timer2"></span>
<span id="timer3"></span>
<span id="timer4"></span>
<span id="timer5"></span>
</body>
<script>
const coinBucket = [5, 10, 20, 60, 90];//number of coin buckets
const GSR = (func, ...args) =>// google.script.run to promise
new Promise((resolve, reject) =>
google.script.run
.withSuccessHandler(resolve)
.withFailureHandler(reject)
[func](...args)
);
const clearStack = new Map();//map to store timerObjects
function generateCoins(result, i) {
const timer = clearStack.get(i) || new timerObject(i);
clearStack.set(i, timer);
timer.stopTimer();
timer.startTimer(result);
}
class timerObject {
constructor(id) {
this.elementId = 'timer' + (id + 1);
this.timerIds = [];
}
startTimer(duration) {
const display = document.getElementById(this.elementId);
this.timerIds.push(
setInterval(() => {
const hours = parseInt(duration / 1000 / 60 / 60, 10),
minutes = parseInt((duration / 1000 / 60) % 60, 10),
seconds = parseInt((duration / 1000) % 60, 10);
display.innerHTML = [hours, minutes, seconds]
.map((e) => ('0' + e).slice(-2))
.join(':');
duration = duration - 1000;
if (duration < 0) this.stopTimer();
}, 1000)
);
}
stopTimer() {
this.timerIds.forEach(clearInterval);
this.timerIds = [];
}
}
document.addEventListener('DOMContentLoaded', function () {
setInterval(function () {
Promise.all(
coinBucket.map((bucket) => GSR('getCoins', bucket))
).then((values) => values.forEach(generateCoins));
}, 10000);
});
</script>
</html>