【问题标题】:How to Promise.all multiple arrays of mongoose document inserts如何 Promise.all 多个 mongoose 文档插入数组
【发布时间】:2016-12-24 13:22:31
【问题描述】:

我正在尝试使用他们的 Mongoose 模型将文档插入 MongoDB,并且我想使用 Promise。由于此数据来源于 MSSQL 数据库,因此每个集合中的文档与其他集合中的文档具有外键关系。

示例代码如下:

const Promise = require('bluebird');
const mongoose = require('mongoose');
const Make = Promise.promisifyAll(require('../models/make-model'));
const Nameplate = Promise.promisifyAll(require('../models/nameplate-model'));
const Vehicle = Promise.promisifyAll(require('../models/vehicle-model'));

const { makes, nameplates, vehicles } = require('./sqlExport.json');

const logErr = (err) => console.error(err);

Promise.resolve(
  mongoose.connection.db.dropDatabase()
)
.then(() => (
  Promise.all(
    makes.map(make => (
      Make.create(make).then(makeRes => console.log(`Created make ${makeRes}`))
    ))
  )),
  logErr
)
.then(() => (
  Promise.all(
    nameplates.map(nameplate => {
      const { sqlMakeId, sqlModelId, sqlSubModelId } = nameplate;
      return Make.find({ sqlMakeId })
        .then(makeRes => {
          if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`);
          const finalNameplate = Object.assign({}, nameplate, { mongoMakeId: makeRes[0]._id });
          return Nameplate.create(finalNameplate);
        })
        .then(nameplateRes => {
          console.log(`Created nameplate ${nameplateRes}`);
        });
    })
  )),
  logErr
)
.then(() => (
  Promise.all(
    vehicles.map(vehicle => {
      const { sqlVehicleId, sqlMakeId, sqlSubModelId } = vehicle;
      const extraParams = {};
      return Make.find({ sqlMakeId })
        .then(makeRes => {
          if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`);
          extraParams.mongoMakeId = makeRes[0]._id;
          return Nameplate.find({ sqlSubModelId });
        })
        .then(nameplateRes => {
          if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for nameplate.sqlSubModelId: ${sqlSubModelId}`);
          extraParams.mongoNameplateId = nameplateRes[0]._id;
          const finalVehicle = Object.assign({}, vehicle, extraParams);
          return Vehicle.create(finalVehicle);
        })
        .then(vehicleRes => {
          console.log(`Created vehicle ${vehicleRes}`);
        });
    })
  )),
  logErr
)
.catch(logErr);

问题是,有时车辆插入在任何铭牌插入之前全部运行,因此无法找到 mongoNameplateId 的正确文档_id。

完整代码在这里:https://gist.github.com/jeremyjs/1d5509350d3cae69d0e83f1d6478eeb2

【问题讨论】:

  • 看起来应该对我有用。如果您可以将代码剥离到准系统以使调试更容易,那将有所帮助。我喜欢做的一件事是用 setTimeout 调用替换所有异步调用,这些调用在大约一秒钟后解决一个承诺,并打印一条关于它们正在替换的消息,即console.log("Make.find('blah')")
  • NameplateVehicle API 已被承诺,但没有证据表明已调用承诺的方法。 Nameplate.create() 应该是Nameplate.createAsync()Vehicle.create() 应该是Vehicle.createAsync() 吗?
  • @Roamer-1888 好电话。我从未使用过蓝鸟,但查看它声明的文档Note that the original methods on the object are not overwritten but new methods are created with the Async-suffix. For example, if you promisifyAll the node.js fs object use fs.statAsync to call the promisified stat method.

标签: node.js mongodb promise foreign-keys


【解决方案1】:

我通过在我的 mongoose 和 bluebird require 语句下面添加这一行来让它工作:

mongoose.Promise = Promise;

此处的文档:http://mongoosejs.com/docs/promises.html

在这种情况下,不需要来自 bluebird 的 Promise.promisifyAll 模式。

【讨论】:

  • 很好也很简单,但如果这样可行,那么默认的mpromise 似乎也可以使用。你有没有尝试过 Bluebird 和 mongoose.Promise = Promise 行?
  • @Roamer-1888 它确实适用于 mpromise,但 Bluebird 比 mpromise 性能更高。
  • 使用打字稿我不得不这样说:(<any>mongoose).Promise = Promise;
猜你喜欢
  • 2018-01-13
  • 2021-01-10
  • 2020-02-07
  • 2019-07-09
  • 1970-01-01
  • 2018-01-02
  • 2020-12-26
相关资源
最近更新 更多