Node中有没有更好的方式来处理Mongo中的并发?

我正在开发一个API,我们发送从各种GET返回的单个资源的Last-Modifieddate头。

当客户端在该资源上进行PUT / PATCH时,他们可以发送If-Unmodified-Since报头,以确保他们只更新最新版本的资源。

支持这是一种痛苦,因为我希望我的应用程序能够响应以下用例:

  • 您尝试更新的资源不存在(404)
  • 您尝试更新的资源失败的先决条件(412)
  • 处理请求时出错(500)

有没有更好的方式来做到这一点与Mongo,这不涉及到三个单独的Mongo数据库调用,以捕获可能的用例,并返回适当的响应?

我想清理一下:

 // the callback the handler is expecting from the model method below callback(err, preconditionFailed, wasUpdatedBool) // model method var orders = this.db.client({ collection: 'orders' }); var query = { _id: this.db.toBSON(this.request.params.id) }; // does the order exist? orders.findOne(query, function(err, doc) { if(err) { return callback(err); } if(!doc) { return callback(null, null, false); } // are you updating the most recent version of the doc? var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime(); if(ifUnModifiedSince) { query.lastModified = { $lte: ifUnModifiedSince }; orders.findOne(query, function(err, doc) { if(err) { return callback(err); } if(!doc) { return callback(null, true); } //attempt to update orders.update(query, payload, function(err, result) { if(err) { return callback(err); } if(!result) { return callback(null, null, false); } return callback(null, null, result); }); }); } //attempt to update orders.update(query, payload, function(err, result) { if(err) { return callback(err); } if(!result) { return callback(null, null, false); } callback(null, null, result); }); }); 

你有太多的疑问,你可能知道。 这一般的stream程应该是:

  1. 按ID查找文档 – 如果没有find,给404
  2. 检查if-unmodified-since标题是否存在,并将其与文档的修改date进行比较。 问题412(如适用)
  3. 如果允许,更新文档

所以,你的代码应该是这样的:

 var orders = this.db.client({ collection: 'orders' }); var query = { _id: this.db.toBSON(this.request.params.id) }; orders.findOne(query, function(err, order) { if(err) { return callback(err); // Should throw a 500 } if(!order) { return callback(404); } if(self.request.headers['if-unmodified-since']) { var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime(); if(order.lastModified.getTime() > ifUnModifiedSince) { return callback(412); // Should throw a 412 } } // Now do the update orders.update(query, payload, function(err, result) { if(err) { return callback(err); } if(!result) { return callback(null, null, false); } return callback(null, null, result); }); });