为什么我的setInterval在1秒后没有显示每个数字?

时间:2018-06-17 02:41:43

标签: javascript node.js events setinterval

我有一个应用程序应该每1秒运行一个素数。

一切正常:控制台在开头说“开始”,到最后说“结束”。但是,它不会在1秒后显示每个数字,而只是一次显示所有内容。

index.js:

var prime = require('./prime');

prime.on('start', () => console.log("Event Started"));
prime.on('prime', () => { });
prime.on('end', () => console.log("Event Ended"));
prime.start();

prime.js:

var events = require('events');
var util = require('util');
util.inherits(PrimeNumber, events);
var prime = new PrimeNumber();
module.exports = prime;

function PrimeNumber() {
    events.call(this);
    var self = this;
    this.start = () => {
        self.emit('start');
        var interval = setInterval(() => {
            for (var counter = 2; counter <= 2000; counter++) {
                var notPrime = false;
                for (var i = 2; i <= counter; i++) {
                    if (counter % i === 0 && i !== counter) {
                        notPrime = true;
                    }
                }
                if (notPrime === false)
                    self.emit('prime', console.log(counter));
            }
            clearInterval(interval);
            self.emit('end');
        }, 1000);
    }
}

我一直在尝试解决这个问题,所以任何帮助都会受到赞赏!

2 个答案:

答案 0 :(得分:1)

只需对代码进行最少的更改,就可以像这样编写

var events = require('events');
var util = require('util');
util.inherits(PrimeNumber, events);
var prime = new PrimeNumber();
module.exports = prime;

function PrimeNumber() {
    events.call(this);
    var self = this;
    var startAt = 1; // starting position - 1 for the outer loop for each interval
    this.start = () => {
        self.emit('start');
        var interval = setInterval(() => {
            for (var counter = startAt + 1; counter <= 2000; counter++) {
                var notPrime = false;
                for (var i = 2; i <= counter; i++) {
                    if (counter % i === 0 && i !== counter) {
                        notPrime = true;
                        break;
                    }
                }
                if (notPrime === false) {
                    console.log(counter)
                    self.emit('prime', counter);
                    startAt = counter; // save the current prime, so we can start the next interval at the right place
                    return; // don't fall through, because we found a prime
                }
            }
            // if we get here, we've reached 2001 without finding a prime
            clearInterval(interval);
            self.emit('end');
        }, 1000);
    }
}
  

使用class进行更现代化的处理 - 以及稍微简单的算法

const events = require('events');

class PrimeNumber extends events {
    constructor() {
        super();
    }
    start() {
        let primes = [2];
        this.emit('start');
        this.emit('prime', 2)
        let interval = setInterval(() => {
            for (let counter = primes[0] + 1; counter <= 2000; counter++) {
                if (primes.every(p => counter % p !== 0)) {
                    primes.unshift(counter);
                    this.emit('prime', counter);
                    return;
                }
            }
            clearInterval(interval);
            this.emit('end');
        }, 1000);
    }
}
const prime = new PrimeNumber();
module.exports = prime;

答案 1 :(得分:0)

您第一次运行时会清除间隔,这会阻止它再次运行。

以下是setInterval行为的简化版本,可以更清晰地显示:

var interval = setInterval(() => {
    // for loop here

    clearInterval(interval);    // <-- You're clearing the interval here

    self.emit('end');
}, 1000);

最简单的方法可能是在if呼叫周围加clearInterval()来控制停止计时器。