Уменьшить размер стеков вызовов в Javascript - PullRequest
0 голосов
/ 07 января 2020

Когда я знаю, что конкретный вызов является последним в функции, и мне не нужно ничего возвращать из функции, могу ли я уменьшить размер стека вызовов?

Вот пример

constructor(){
    this.processNext = this.a;
}

parse(stream){
    stream.on('data', data => {
        this.start(data);
    })
}

start(data){
    this.data += data;
    //somecode
    this.processNext();
}

a(){
    for(; this.index < this.data.length; this.index++){
        //some code
        if(someCondition) {
            this.processThisNext(this.b);
            break;
        }else if(another condition){
            this.processThisNext(this.c);
            break;
        }
    }
}

b(){
    for(; this.index < this.data.length; this.index++){
        //some code
        if(someCondition) {
            this.processThisNext(this.a);
            break;
        }
    }
}

processThisNext(method){
  this.processNext = method;
  this.processNext();
}
c(){}

Объяснение:

Я разделил код на несколько функций, чтобы уменьшить количество сравнений и сделать его понятным. Я слушаю data событие входного потока. processNext - это прокси-функция, которая всегда вызывается при запуске события data. Значение processNext постоянно меняется в логи c.

Теперь, как вы можете видеть в приведенном выше коде, когда я вызываю processThisNext, я действительно хочу существовать из текущего вызова функции. На данный момент мне не нужно, чтобы это и родительская функция присутствовали в стеке вызовов.

Можно ли как-нибудь это упростить? или уменьшить стек вызовов другим способом?

1 Ответ

0 голосов
/ 07 января 2020

Чтобы выйти из текущего стека вызовов, можно вызвать следующий метод после Promise.resolve - он будет работать как микрозадача после завершения другой синхронной обработки Javascript:

a(){
    for(; this.index < this.data.length; this.index++){
        //some code
        if(someCondition) {
            Promise.resolve().then(() => {
                this.processThisNext(this.b);
            });
            break;
        }else if(another condition){
            Promise.resolve().then(() => {
                this.processThisNext(this.c);
            });
            break;
        }
    }
}

b(){
    for(; this.index < this.data.length; this.index++){
        //some code
        if(someCondition) {
            Promise.resolve().then(() => {
                this.processThisNext(this.a);
            });
            break;
        }
    }
}
...