NestJS中使用Bluebird.map报错TypeError的问题求助
问题与解决:Bluebird.map 抛出
TypeError: obj._then is not a function 环境信息
- @nestjs/core 9.0.0
- bluebird 3.7.2
- @types/bluebird 3.5.38
tsconfig.json 配置
{ "compilerOptions": { "module": "commonjs", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es2017", "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true, "skipLibCheck": true, "strictNullChecks": false, "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, "esModuleInterop": true } }
报错代码
await Bluebird.map(dataAccessories, accessory => { const { accessory_id, quantity } = accessory return Accessory.update({ where: { id: accessory_id }, data: { inventory: { increment: quantity } } }) }, { concurrency: 5 })
错误信息
TypeError: obj._then is not a function at tryConvertToPromise (node_modules/bluebird/js/release/thenables.js:19:21) at MappingPromiseArray._promiseFulfilled (node_modules/bluebird/js/release/map.js:81:28) at MappingPromiseArray.PromiseArray._iterate (node_modules/bluebird/js/release/promise_array.js:115:31) at MappingPromiseArray.init (node_modules/bluebird/js/release/promise_array.js:79:10) at MappingPromiseArray._asyncInit (node_modules/bluebird/js/release/map.js:37:10) at _drainQueueStep (node_modules/bluebird/js/release/async.js:97:12) at _drainQueue (node_modules/bluebird/js/release/async.js:86:9) at Async.Object.<anonymous>.Async._drainQueues (node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues (node_modules/bluebird/js/release/async.js:15:14)
解决方法
这个错误的核心是Bluebird无法识别Accessory.update返回的Promise对象——Bluebird内部依赖私有属性_then判断是否为可处理的Promise,而你使用的ORM返回的可能是原生Promise或自定义Promise,不具备该属性。以下是三种可行方案:
方案1:将ORM返回值转为Bluebird Promise
用Bluebird.resolve()包裹ORM的返回结果,强制转为Bluebird兼容的Promise:
await Bluebird.map(dataAccessories, accessory => { const { accessory_id, quantity } = accessory return Bluebird.resolve(Accessory.update({ where: { id: accessory_id }, data: { inventory: { increment: quantity } } })) }, { concurrency: 5 })
方案2:改用原生Promise实现并发控制
如果不需要Bluebird的特定功能,可直接用原生Promise结合分批逻辑实现并发控制:
const concurrency = 5; // 分批执行,控制并发数 for (let i = 0; i < dataAccessories.length; i += concurrency) { const batch = dataAccessories.slice(i, i + concurrency); await Promise.all(batch.map(accessory => { const { accessory_id, quantity } = accessory return Accessory.update({ where: { id: accessory_id }, data: { inventory: { increment: quantity } } }) })); }
方案3:配置ORM使用Bluebird作为Promise库
部分ORM支持指定Promise库,以TypeORM为例,可在配置中直接设置使用Bluebird:
// TypeORM配置示例 { type: 'mysql', host: 'localhost', port: 3306, // ...其他数据库配置 promiseLibrary: require('bluebird') }
配置后ORM返回的就是Bluebird Promise,可直接被Bluebird.map识别处理。
内容的提问来源于stack exchange,提问作者XanhZ
相关产品推荐
相关产品推荐

