Невозможно вызвать функцию, использующую это в классе - PullRequest
1 голос
/ 29 марта 2020

У меня есть класс с именем Scheduler, который выполняет задание cron с использованием модуля cron. Я создал функцию для получения разницы дней между двумя датами, эта функция работает, если я вызываю ее вне итерации задания cron, в противном случае она вернет

TypeError: this.getDaysDifference не является функцией

вот мой код:

const CronJob = require('cron').CronJob;

class Scheduler {

    async start() {

        // HERE WORKING
        console.log(this.getDaysDifference(new Date('2020-03-29'), new Date('2020-03-30')));

        const job = new CronJob('0 */1 * * * *', async function () {
            let messages = await MessageModel.find();
            for (const msg of messages) {
                // HERE NOT WORKING
                console.log(this.getDaysDifference(new Date(), msg.lastScheduler));
            }
        });

        job.start();
    }

    getDaysDifference = function(start, end) {
        const _MS_PER_DAY = 1000 * 60 * 60 * 24;
        const utc1 = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
        const utc2 = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
        return Math.floor((utc2 - utc1) / _MS_PER_DAY);
    }
}

exports.Scheduler = Scheduler;

Ответы [ 2 ]

3 голосов
/ 29 марта 2020

this.getDaysDifference не указывает на экземпляр класса Scheduler в вашем обратном вызове, поскольку вы использовали function.

. Есть два способа исправить это. :

  • Используйте функцию стрелки () => {}, которая очень прямолинейна.

  • Свяжите this с вашим экземпляром явно, используя functionObj.bind(yourInstance).

Вы можете использовать функцию стрелки, которая связывает this с лексическим этим в вашем определении обратного вызова:

new CronJob('0 */1 * * * *', async () => {
     let messages = await MessageModel.find();
     for (const msg of messages) {
         //this will be the lexical  this i.e. point to the instance o sthe Scheduler class
         console.log(this.getDaysDifference(new Date(), msg.lastScheduler));
        }
});

Решение с использованием bind, где вы явно привязываете значение this к экземпляру вашего класса:

let cronJobCallback = async function () {
      let messages = await MessageModel.find();
      for (const msg of messages) {
      // HERE NOT WORKING
      console.log(that.getDaysDifference(new Date(), msg.lastScheduler));
      }
 }
 cronJobCallback = cronJobCallback.bind(this);
 new CronJob('0 */1 * * * *', cronJobCallback);
1 голос
/ 29 марта 2020

Когда выполняется обратный вызов, данный CronJob, он будет в другом контексте и, следовательно, this не будет ссылаться на ваш экземпляр Scheduler (возможно, на экземпляр CronJob). Попробуйте сделать захват this, прежде чем приступить к обработке CronJob:

    async start() {

        // HERE WORKING
        console.log(this.getDaysDifference(new Date('2020-03-29'), new Date('2020-03-30')));
        const that = this;
        const job = new CronJob('0 */1 * * * *', async function () {
            let messages = await MessageModel.find();
            for (const msg of messages) {
                // HERE NOT WORKING
                console.log(that.getDaysDifference(new Date(), msg.lastScheduler));
            }
        });

        job.start();
    }

Альтернатива, используйте функцию стрелки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...