假设我在一个对象中有一堆任务,每个任务都有一个日期对象。我想知道是否有可能让对象内的任务在单个进程中运行并在调用日期时触发。
这是一个例子:
var tasks = [
"when": "1501121620",
"what": function(){
console.log("hello world");
},
"when": "1501121625",
"what": function(){
console.log("hello world x2");
},
]
我很乐意将这些存储在数据库中,并且从字符串中对 what
脚本进行eval
处理。我需要一个正确方向的点。我在 Node 世界中从未见过这样的事情。
我正在考虑使用 hotload
并使用文件系统,因此我不需要处理数据库。
我应该看看setInterval
还是有更复杂的东西?我知道像 cron 之类的东西存在,问题是我需要所有这些任务在已经存在的正在运行的进程中发生。我需要能够在不结束进程的情况下将新任务添加到队列中。
为了添加一些上下文,我需要某种方法对 socket.io .emit()
函数进行排队。
最佳答案
不要重新发明轮子。使用cron来自 npm 的包。他是纯粹用 js 编写的(使用下面的第二种变体)。因此,所有这些任务都将发生在现有的正在运行的进程中。例如,您可以像这样创建CronJob
:
var CronJob = require('cron').CronJob;
var job = new CronJob(1421110908157);
job.addCallback(function() { /* some stuff to do */ });
在纯 JavaScript 中,您只能通过 setTimeout
和 setInterval
方法来实现。有两种变体:
1)设置间隔回调,它将检查您的任务队列并在适当的时间执行回调:
setInterval(function() {
for (var i = 0; ii = tasks.length; ++i) {
var task = tasks[i];
if (task.when*1000 < Date.now()) {
task.what();
tasks.splice(i,1);
--i;
}
};
}, 1000);
As you see accuracy of callback calling time will be dependent on interval time. Less interval time => more accuracy, but also more CPU usage.
2) 围绕您的任务创建包装器。因此,当您想要添加新任务时,您将调用某个方法 addTask
,该方法将通过您的任务回调调用 setTimeout
。请注意,setTimeout
的最长时间为 2147483647 毫秒(大约 25 天)。因此,如果您的时间超过了最大时间,您必须使用回调设置最大时间超时,该回调将使用剩余时间设置新的超时。例如:
var MAX_TIME = 2147483647;
function addTask(task) {
if (task.when*1000 < MAX_TIME) {
setTimeout(task.what, task.when);
}
else {
task.when -= MAX_TIME/1000;
setTimeout(addTask.bind(null, task), MAX_TIME);
}
}
关于node.js - 在单个进程中排队 javascript 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27910891/