Firebase clearTimeout不会停止setTimeout

时间:2018-01-11 16:38:37

标签: javascript node.js firebase google-cloud-functions

如何在" 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);
            }
    };
}

1 个答案:

答案 0 :(得分:-1)

这个功能有很多错误。

首先,我不清楚为什么要在此函数中使用setTimeout()。事实上,使用云函数的setTimeout()几乎没有有效的用例。函数应该尽可能快地执行,而setTimeout只会给你的处理带来额外的成本。云功能无法让您运行&#34;后台工作&#34;在函数调用之后幸存下来 - 这不是它的工作方式。

其次,您在此处执行异步工作,但您不是returning a promise来指示该工作何时完成。如果您在工作完成时没有回复已经解决的承诺,那么您的功能很可能会出现奇怪的问题,包括未按照您的预期完成的工作。