使用 nano-promises 强制同步 CouchDB 查询和更新

Using nano-promises to force synchronous CouchDB queries and updates

我正在使用 nano-promise 尝试强制执行 node.js 到 运行 中的以下代码。然而,在第一个 CouchDB 插入完成之前,下面的承诺似乎仍然完成。这会导致一个问题,因为稍后的承诺将包含查询 CouchDB 的代码,并期望前面步骤中的代码是完整的。我认为问题是因为 return 在 db.get 之后和 db.get 完成之前立即执行。有人对如何解决这个问题有什么建议吗?

var nano = require('nano')('http://localhost:5984');
var Promise = require('nano-promise');
var db = nano.db.use('myDB');

var promise = new Promise(function (resolve, reject) {
    resolve(request);
}).then(function (args) {
    console.log('step 1');
    console.log(args.body);
    db.get(args.body.id, function(err, body) {
        var doc_update = body;
        if (!err) {
            doc_update.beginDate = args.body.startDate;
            doc_update.updated = new Date();
            db.insert(doc_update, args.body.id, function(err, body){
                if(!err){
                    console.log('Database UPDATED (Step 1)');
                }
            });
        } else {
            doc_update.updated = new Date();
            db.insert(doc_update, args.body.id, function(err, body){
                if (err) throw err; 
            });
        }
    });
    return new Promise.Arguments(args);
}).then(function (args) {
    console.log(args.body);
    return new Promise.Arguments(args);
});
promise.then(function (args) {
    console.log(args.body);
    return new Promise.Arguments(args);
});
promise.then(function (args) {
    console.log(args.body);
});

这段代码的输出是:

step 1
{id: '123',
startDate: '2017-12'}
step 2
{id: '123',
startDate: '2017-12'}
step 3
{id: '123',
startDate: '2017-12'}
step 4
{id: '123',
startDate: '2017-12'}
Database UPDATED (Step 1)

输出应该是:

step 1
{id: '123',
startDate: '2017-12'}
Database UPDATED (Step 1)
step 2
{id: '123',
startDate: '2017-12'}
step 3
{id: '123',
startDate: '2017-12'}
step 4
{id: '123',
startDate: '2017-12'}

根据 documentation,您使用的 nano-promise 是错误的。您使用它来创建一个 returns 承诺插入和获取的数据库对象。

你似乎有三层嵌套的承诺,代码应该是这样的:

var db = prom(nano('http://localhost:5984')).db.use('myDB');

var promise = Promise.resolve(request)
.then(function (args) {
  console.log('step 1');
  console.log(args.body);
  return db.get(args.body.id)
  .catch(
    err => {
      var doc_update = body;
      doc_update.updated = new Date();
      return db.insert(doc_update, args.body.id)
      .then(x=>args);
    }
  )
  .then(
    body => {
      var doc_update = body;
      doc_update.beginDate = args.body.startDate;
      doc_update.updated = new Date();
      return db.insert(doc_update, args.body.id)
      .then(
        ok => {
          console.log('Database UPDATED (Step 1)');
          return args;
        },
        err => {
          console.log("Failed UPDATE (Step 1)");
        }
      );
    }
  )
}).then(function (args) {
  console.log(args.body);
  return args;
});