使用async/await通过IMAP获取邮件出现TypeError问题求助
解决IMAP库async/await调用
openBox时的TypeError: cb is not a function问题 你踩了一个回调转Promise的典型坑——你使用的这个imap库的openBox方法并没有原生支持Promise,它只接受回调函数作为第三个必填参数。当你直接用await调用它时,相当于没有传递这个必需的回调参数,库内部执行到cb(err, self._box)时,cb是undefined,自然就抛出了类型错误。
正确的async/await封装方式
你需要手动把openBox包装成返回Promise的函数,才能用await来调用:
var Imap = require('imap'); var inspect = require('util').inspect; var imap = new Imap({ user: 'mymailname@mail.com', password: 'mymailpassword', host: 'imap.mail.com', port: 993, tls: true }); // 手动将openBox封装为Promise版本 const openInbox = () => { return new Promise((resolve, reject) => { imap.openBox('INBOX', true, (err, inbox) => { if (err) reject(err); else resolve(inbox); }); }); }; imap.once('ready', async () => { console.log('ready'); try { const inbox = await openInbox(); console.log('Inbox: ' + inspect(inbox)); // 用inspect能更清晰打印对象结构 } catch (error) { console.log('Error: ', error); } }); imap.connect();
为什么原来的代码会出错?
你之前的openInbox函数里直接await imap.openBox(...),但imap.openBox并不返回Promise,它的设计就是依赖回调函数处理结果。当你不传回调时,库内部的代码找不到要执行的cb,就触发了TypeError。
而嵌套回调的方式能正常工作,是因为你严格按照库的API要求,传递了正确的回调函数。
简化封装小技巧
如果之后要封装更多这个库的回调式方法,可以用Node.js内置的util.promisify工具来简化:
const { promisify } = require('util'); // 注意要绑定imap上下文,避免this指向错误 const openBoxAsync = promisify(imap.openBox.bind(imap)); // 之后直接调用:await openBoxAsync('INBOX', true)
内容的提问来源于stack exchange,提问作者Loup G
相关产品推荐
相关产品推荐

