代码之家  ›  专栏  ›  技术社区  ›  Roledenez

回调函数在节点调度程序中不工作

  •  2
  • Roledenez  · 技术社区  · 8 年前

    我已经成功地用node.js编写了一个代码来读取邮箱中未看到的电子邮件。当我在普通的javascript文件中运行它时,它工作得很好。现在我想安排脚本每30秒运行一次。所以用node scheduler编写了一个代码片段,如下所示。运行这个我刚得到 reading unread emails....### 作为输出, console.log(msg); 不打印任何内容。如果我在没有节点调度程序的情况下运行这个,它会很好地工作。可能有什么问题?我试过了 await 关键字 email.unreadEmail 功能,也没用。

    我认为这是由于异步行为而发生的事情。如果有的话,有没有办法把这段代码转换成承诺?我有点配置,因为在IMAP接口中有多个下一个回调。

    schedule.scheduleJob('*/30 * * * * *', () => {
    
        logger.info(`scheduler runs at ${new Date()} for check unread emails`);
        let email = new mail.default();
        email.unreadEmail((msg) => {
            console.log(msg);
        });
    
    });
    

    这是阅读电子邮件的代码

    unreadEmail(callback){
    
            logger.info(`reading unread emails....###`);
    
           imap.once('ready', () => {
    
                openIncidents((err, box) => {
                    if (err) throw err;
                    imap.search([ 'UNSEEN'], (err, results) => {
                        if (err) throw err;
    
                        try{
                            // var f = imap.fetch(results, { bodies: '',markSeen: true });
                            var f = imap.fetch(results, { bodies: '' });
                            f.on('message', (msg, seqno) => {
                                console.log('Message #%d', seqno);
                                var prefix = '(#' + seqno + ') ';
                                msg.on('body', (stream, info) => {
    
                                    simpleParser(stream, (err, mail) => {
    
                                        callback(mail.subject);
    
                                    });
    
                                    // stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
                                });
                                msg.once('attributes', function(attrs) {
                                    logger.info(prefix + 'Attributes: %s', inspect(attrs, false, 8));
                                });
                                msg.once('end', function() {
                                    logger.info(prefix + 'Finished');
                                });
                            });
                            f.once('error', function(err) {
                                logger.error('Fetch error: ' + err);
                            });
                            f.once('end', function() {
                                logger.info('Done fetching all messages!');
                                imap.end();
                            });
                        }catch (e) {
                            logger.error('Error from fetching mails, probably there are no unseen emails in mailbox');
                        }
    
                    });
                });
            });
    
            logger.info(`end of the email function....###`);
    
        }
    

    更新

    这种行为与 setInterval 功能

    setInterval(()=>{
    email.unreadEmail((msg)=>{...})}, 30000)
    
    1 回复  |  直到 7 年前
        1
  •  5
  •   Lance Whatley    7 年前

    imap 'ready' 新的IMAP连接的事件在身份验证时仅触发一次(请参见代码 _login https://github.com/mscdex/node-imap/blob/master/lib/Connection.js#L1604

    imap.once('ready' ... 在时间表内,您应该将时间表放在 回拨。我希望像下面这样的东西能起作用 imap.once('ready', () => { ... unreadEmail

    imap.once('ready', () => {
      setInterval(() => {
    
        logger.info(`scheduler runs at ${new Date()} for check unread emails`);
        let email = new mail.default();
        email.unreadEmail((msg) => {
            console.log(msg);
        });
    
      }, 30000);
    });