如何在" Firebase云功能"上的onWrite事件开始之前停止setTimeout功能?我尝试使用setTimeout,但clearTimeout不会停止setTimeout。
P.S。:我已经将Firebase面板的脚本超时从60秒(默认)提升到360秒。
var timeOutOnline = {};
exports.online = functions.database.ref('/server/{serverId}/online/time').onWrite(event => {
const serverId = event.params.serverId;
var time = event.data.val();
var lastDateOnline = new Date( time * 1000);
var dateString = lastDateOnline.toGMTString();
clearTimeout(timeOutOnline[serverId]);
refGet = db.ref('/server/'+serverId+'/online/');
refGet.once('value').then(function(snapshot) {
var onlineSnap = snapshot.val();
if (onlineSnap && onlineSnap.alarm == true) {
sendMail(serverId,false, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,false);
} else {
timeOutOnline[serverId] = setTimeout(function() {
sendMail(serverId,true, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,true);
}, 21000);
}
});
return true;
});
更新 现在我使用promise,但是clearTimeout仍然无效,不清除setTimeout函数。我做错了什么?
var timeOutOnline = {};
exports.online = functions.database.ref('/server/{serverId}/online/time').onWrite(event => {
const serverId = event.params.serverId;
var time = event.data.val();
var lastDateOnline = new Date( time * 1000);
var dateString = lastDateOnline.toGMTString();
console.log(v);
if(!timeOutOnline[serverId]) {
timeOutOnline[serverId] = [];
} else {
timeOutOnline[serverId].length;
for (var i = 0; i < timeOutOnline[serverId].length; i++) {
if (timeOutOnline[serverId][i]) {
timeOutOnline[serverId][i].cancel();
timeOutOnline[serverId][i] = null;
}
}
}
timeOutOnline[serverId] = timeOutOnline[serverId].filter(n => n);
refGet = db.ref('/server/'+serverId+'/online/');
refGet.once('value').then(function(snapshot) {
var onlineSnap = snapshot.val();
if (onlineSnap && onlineSnap.alarm == true) {
sendMail(serverId,false, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,false);
} else {
timeOutOnline[serverId].push(waitForServer(210000));
var index = timeOutOnline[serverId].length - 1;
return timeOutOnline[serverId][index].promise.then(function(i) {
console.log('Server '+ serverId + ' not responding from '+dateString);
sendMail(serverId,true, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,true);
});
}
});
return true;
});
function waitForServer(ms) {
var timeout, promise;
promise = new Promise(function(resolve, reject) {
timeout = setTimeout(function() {
resolve('timeout done');
}, ms);
});
return {
promise:promise,
cancel:function(){
console.log('cancel timeout: '+timeout);
clearTimeout(timeout);
}
};
}
答案 0 :(得分:-1)
这个功能有很多错误。
首先,我不清楚为什么要在此函数中使用setTimeout()。事实上,使用云函数的setTimeout()几乎没有有效的用例。函数应该尽可能快地执行,而setTimeout只会给你的处理带来额外的成本。云功能无法让您运行&#34;后台工作&#34;在函数调用之后幸存下来 - 这不是它的工作方式。
其次,您在此处执行异步工作,但您不是returning a promise来指示该工作何时完成。如果您在工作完成时没有回复已经解决的承诺,那么您的功能很可能会出现奇怪的问题,包括未按照您的预期完成的工作。