美文网首页编程语言爱好者程序园Nodejs
Nodejs下实现邮件的同步读取 2

Nodejs下实现邮件的同步读取 2

作者: 赵阳_c149 | 来源:发表于2019-05-14 09:45 被阅读0次

    之前的一篇文章中介绍了在Nodejs下如何实现邮件的同步读取【1】,基于imap,对与库中的方法用wrap进行了包装,实现了同步行。但是,从代码的实现来看,仍然存在着两个问题。首先是实现同步关闭连接的方法必须和读取邮件的“配对使用”。 其次,当多次调用读取邮件的方法时候,会引起emitter MaxListeners error。

    对于第一个问题可以修改结束imap连接的方法,使其在邮件读取和解析完成之后执行,也就是说作为回调函数放入promise链:

    async function endAsync(message = null) {    return new Promise(function (resolve, nay) {        imap.on('end', function () {            resolve(message);        });        imap.end();    });}
    
    …
    ).then(function (messages) {    return endAsync(messages[messages.length - 1]);}).then(function (message) {    return message;})    .catch(function (error) {        console.error("Oops:", error.message);        imap.end();    })
    

    对于第二个问题,错误的信息是:

    (node:3133) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 end listeners added. Use emitter.setMaxListeners() to increase limit
    
    

    在nodejs的官方文档上可以找到相应的说明:

    By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks.

    默认情况下,当为同一个事件添加了超过10个listener的时候,就会打印出一条警告信息。这一默认行为有助于发现内存泄漏。

    正向我之前的一篇文章【2】中讲到的,Javascript中,javascript runtime还维护着第三类内存空间,事件队列(Queue),因此不得不将事件的listener考虑到内存管理的范畴之内。但是并不想通过增加允许的listener数量来回避这个问题,因为有一种更好的办法。

    Using the eventEmitter.once() method, it is possible to register a listener that is called at most once for a particular event. Once the event is emitted, the listener is unregistered and then called.

    当用once注册listener的时候,它只会为一个特定的事件调用一次,一旦事件触发了,listener同样会被触发,但是之后就会被删除。

    async function endAsync(message = null) {    return new Promise(function (resolve, nay) {        imap.once('end', function () {            resolve(message);        });        imap.end();    });}
    

    解决了这两个问题之后,回看这个简单的例子不难发现,imap对象是一个全局变量,或者说是一个singleton模式的应用,所以才会有setMaxListeners的问题。

    const imap = new Imap({    user: 'user',    password: 'password',    port: 993,    host: 'host',    tls: true});
    

    通过这两篇文章介绍,读者应该可以了解我是如何实现Nodejs下邮件的同步读取。并且,文章描述了在这一过程中出现的问题和相应的解决方法。

    实例代码可以在github上找到【3】。

    【1】Nodejs下实现邮件的同步读取 1
    【2】Nodejs Event Loop
    【3】test_imap_sample_end_once.js

    相关文章

      网友评论

        本文标题:Nodejs下实现邮件的同步读取 2

        本文链接:https://www.haomeiwen.com/subject/teyjaqtx.html