M
M
Mikhail2017-07-05 16:25:35
JavaScript
Mikhail, 2017-07-05 16:25:35

Why such strange behavior in JS?

Hello. I will try to briefly describe the problem. There is a class:

class RedisAPI {
    constructor(redis) {
        this.masterID = new Array(); //здесь хранятся уникальные ID всех воркеров
        this.master = redis.createClient();
    }

    addWorker(id) {
        this.masterID.push(id);
        console.log(`Worker ${id} is working!`);
    }

    //отправление сообщения на обработку одному из воркеру
    emit() {
        let needID = this.masterID.splice(0, 1);
        console.log(`arr: ${this.masterID.length}; first: ${needID[0]}`);
        this.masterID.push(needID[0]);
    }

    //отправление сообщения на обработку одному из воркеров каждые ms секунд
    emitTimeout(ms) {
        setInterval(() => {
            this.emit();
        }, ms);
    }
}

After two asynchronous data additions to RedisAPI.masterID, the code starts to behave strangely, namely:
const queue = new RedisAPI(redis);
queue.emitTimeout(1000);

And in the console I see:
arr: 1; first: undefined
arr: 1; first: id1499261061279
arr: 1; first: undefined
arr: 1; first: id1499261061279
And so it alternates. That is, it is not possible to correctly remove the first element of the array, although it is always there. What could be the problem?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Abdula Magomedov, 2017-07-05
@Avarskiy

//отправление сообщения на обработку одному из воркеру
    emit() {
        let length = this.masterID.length;
        let needID = this.masterID.splice(0, 1);
        console.log(`arr: ${length}; first: ${needID[0]}`);
        this.masterID.push(needID[0]);
    }

K
Kovalsky, 2017-07-05
@lazalu68

Why is this all?

let needID = this.masterID.splice(0, 1);
...
this.masterID.push(needID[0]);

You use this algorithm to put the first element in the last place. If I didn't know the task, I would tell you "why is it so difficult, just do this.masterID.reverse()" . In addition, you do not check whether the queue is empty anywhere, in any case, you are doing your dark work.
With verification, everything works without tricks
class RedisAPI {
    constructor() {
        this.masterID = new Array(); //здесь хранятся уникальные ID всех воркеров
    }

    addWorker(id) {
        this.masterID.push(id);
        console.log(`Worker ${id} is working!`);
    }

    //отправление сообщения на обработку одному из воркеру
    emit() {
        if (this.masterID.length) {
            let needID = this.masterID.splice(0, 1);
            console.log(`arr: ${this.masterID.length}; first: ${needID[0]}`);
            this.masterID.push(needID[0]);
        } else {
            console.log('The queue is empty!');
        }
    }

    //отправление сообщения на обработку одному из воркеров каждые ms секунд
    emitTimeout(ms) {
        setInterval(() => {
            this.emit();
        }, ms);
    }
}

var queue = new RedisAPI();

queue.emitTimeout(1000);

setTimeout(function() {
    queue.addWorker(42);
}, 1500);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question