Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS后台作业永远不会执行,永远循环_Javascript_Node.js_Asynchronous_Background Process_Job Scheduling - Fatal编程技术网

Javascript NodeJS后台作业永远不会执行,永远循环

Javascript NodeJS后台作业永远不会执行,永远循环,javascript,node.js,asynchronous,background-process,job-scheduling,Javascript,Node.js,Asynchronous,Background Process,Job Scheduling,我有一个模块可以在NodeJS中启动一些后台作业(作业是HTTP请求),下面是它的简化版本: var util = require('util'), EE = require('events').EventEmitter, Winston = require('winston'); var logger = new Winston.Logger({transports: [new Winston.transports.Console()]}); function Bot() {

我有一个模块可以在NodeJS中启动一些后台作业(作业是HTTP请求),下面是它的简化版本:

var
util    = require('util'),
EE  = require('events').EventEmitter,
Winston = require('winston');
var logger = new Winston.Logger({transports: [new Winston.transports.Console()]});

function Bot() {
    EE.call(this);
    this.model = ['job1','job2','job3'];
    // null = never had a job, false = job started, true = job finished
    this.jobs = {
        'job1': null,
        'job2': null,
        'job3': null };
    var mirror = this;

    function start_job(job) {
        var t = Math.floor(Math.random() * 10 + 1) * 1000;
        logger.info('calling ' + job + ' for t=' + t);
        setTimeout(function() {
            logger.info('finished ' + job);
            mirror.jobs[job] = true;
        }, t);
    }

    this.on('start', function() {
        logger.info('Starting');
        while (mirror.isRunning()) {
            for (var i=0; i<mirror.model.length; i++) {
                var job = mirror.model[i];
                var oldJob = mirror.jobs[job];
                if (oldJob === null || oldJob === true) {
                    mirror.jobs[job] = false;
                    start_job(job);
                }
            }
            // mirror.shutdown();
        }
        logger.info('Shutting down');
    });
}

util.inherits(Bot, EE);

Bot.prototype.shutdown = function() {
    this.running = false;
};
Bot.prototype.start = function() {
    this.running = true;
    this.emit('start');
};
Bot.prototype.isRunning = function() {
    return this.running;
};

var bot = new Bot();
bot.start();
脚本此时挂起,处于无限循环中

现在,如果我在第一次循环迭代后通过取消注释
mirror.shutdown()
停止,作业将按预期启动:

info: Starting
info: calling job1 for t=6000
info: calling job2 for t=9000
info: calling job3 for t=1000
info: Shutting down
info: finished job3
info: finished job1
info: finished job2
但这是不好的。我不知道为什么会发生这种情况,但我对Node还不熟悉,还在为一些概念而挣扎


我知道有一个名为的模块,但我不知道这是否适用于这里,也不知道它的稳定性如何(似乎不是一个活动项目)。我可以试试,但在继续之前我仍然想了解这个问题。

问题是
node.js
是单线程的。while循环继续运行并占用事件循环,因此
setTimeout
没有机会触发。您需要将其设置为
setInterval
(或者可能是递归的
setTimeout
),而不是使用while循环来启动作业。例如:

this.on('start', function() {
    logger.info('Starting');
    for (var i=0; i<mirror.model.length; i++) {
        var job = mirror.model[i];
        var oldJob = mirror.jobs[job];
        if (oldJob === null || oldJob === true) {
            mirror.jobs[job] = false;
            start_job(job);
        }
    }
    setTimeout(function(){mirror.start()}, 50);
    logger.info('Shutting down');
});
this.on('start',function()){
logger.info(“启动”);

对于(var i=0;我相信你,它是有效的。如果你不介意,我可以问一个后续问题吗?写
setTimeout(function(){mirror.start()},50);
setTimeout(mirror.start,50)之间有什么区别吗;
?@user0000001第二个方法将调用正确的方法,但是
这个
将是全局的,而不是您所期望的。
this.on('start', function() {
    logger.info('Starting');
    for (var i=0; i<mirror.model.length; i++) {
        var job = mirror.model[i];
        var oldJob = mirror.jobs[job];
        if (oldJob === null || oldJob === true) {
            mirror.jobs[job] = false;
            start_job(job);
        }
    }
    setTimeout(function(){mirror.start()}, 50);
    logger.info('Shutting down');
});