You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:30:29