Mocha:无论时间限制如何,承诺超时

Mocha: Promises timing out no matter the time limit

我正在做一个面试项目,我必须为其添加一个端点,让我 POST 一系列产品(列表)并且它应该创建它们(MongoDB + Mongoose) 或相应地更新它们。问题是我显然没有正确处理 Promises,而且我的测试超时了。 这是规范:

    it.only('should create listings or update them if they already exist, incrementing the quantity with the difference ' +
      'between the current sold_quantity and the initial_sold_quantity', (done) => {
      var iPhone = { ... };
      var samsung = { ... };
      request(app).post('/listings/myEndpoint').send([iPhone, samsung]).expect(200, {
        created: 1,
        updated: 1
      }, done);
    });
exports.myEndpoint = (req, res) => {
  var listings = req.body;
  var created, updated = 0;

  listings.forEach(reqListing => {
    Listing.findOne({ listing_id: reqListing.listing_id })
      .then(foundListing => {
        if (!foundListing) {
          var newListing = reqListing;
          newListing.initial_sold_quantity = newListing.sold_quantity;
          Listing.create(newListing);
          created++;
        } else {
          var newQuantity = reqListing.sold_quantity - foundListing._doc.initial_sold_quantity;
          if (foundListing._doc.quantity != newQuantity) {
            foundListing._doc.quantity = newQuantity;
            foundListing.save();
            updated++;
          }
        }
      });
      return {
        created: created,
        updated: updated
      };
  });
};

我尝试过的东西:

  1. 给它更多的时间。我尝试更改 Mocha 测试的默认超时时间,但不管是 2 秒还是 20 秒,它仍然会超时。

  2. 隔离更新与创建。不管我只是更新一个产品还是只创建一个产品,它仍然会超时。

  3. 删除逻辑。据我检查, if/else 块内发生的事情并不重要,因为它仍然会给我超时。所以即使代码看起来像这样:

exports.myEndpoint = (req, res) => {
  var listings = req.body;
  var created, updated = 0;

  listings.forEach(reqListing => {
    Listing.findOne({ listing_id: reqListing.listing_id })
      .then(foundListing => {
        if (!foundListing) {
          console.log("creating");
        } else {
          console.log("updating");
        }
      });
      return {
        created: created,
        updated: updated
      };
  });
};

它仍然会超时。

在 Nodeiflux Discord 服务器中询问了一些问题后,我设法找到了一个解决方案,也许不是最漂亮的,因为它没有使用 async/await 但我不应该改变项目太多,所以我会在没有 async/await.

的情况下保留它

首先,修复 post 的问题后出现的愚蠢问题:

var created = 0, updated = 0;

而不是不初始化 created

其次,在内部使用带有 Promises 的 forEach 没有太大意义,因为它会丢弃内部 returning 的任何内容,所以我将 return 放在 forEach 子句之外并更改了forEach 迭代代替地图。我还利用 Promise.all() 在 returning:

之前获得所有要解决的承诺
exports.upsert = (req, res) => {
  var listings = req.body;
  var created = 0, updated = 0;
  var allowedArrayLength = 50;
  return Promise.all(listings.map(reqListing =>
    Listing.findOne({
        listing_id: reqListing.listing_id
      })
      .then(foundListing => {
        if (!foundListing) {
          createListing(reqListing);
          created++;
        } else {
          var prevQuantity = foundListing.quantity;
          if (updateListing(reqListing, foundListing).quantity > prevQuantity) {
            updated++;
          }
        }
      })
  )).then(() => ({ created: created, updated: updated }));
};