抽象函数为了让选择返回promises或回调

时间:2017-01-25 00:07:12

标签: javascript node.js callback promise

我不知道它可能是反模式。

很快很年轻的开发人员就会加入我们的开发团队,我想让他们选择是否要使用带回调或Promises模式的模块。

此功能基本上将数据保存到数据库中。我重复db.insert流程以抽象函数,但还有另一种方法吗?



function create(data, callback) {
  
  if(callback) {
     db.insert(data, function(err, doc) { 
         return callback(err, doc);
    });
    
    
  } else {
    return new Promise(function(res, rej) {
      db.insert(data, function(err, doc) {
        if(err) {
          return reject(err);
        }
        return resolve(doc); 
      
      });
    });
  }
}




3 个答案:

答案 0 :(得分:1)

我喜欢蓝鸟.asCallback(...)方法:

function somethingAsync(cb) {
  return somePromise().asCallback(cb);
}

...基本上,你返回一个promise 调用一个回调(如果有一个)。因此,它可以以任何一种方式使用。如果你不想采用Bluebird,你基本上可以做同样的事情:

function somethingAsync(cb) {
  var promise = somePromise();
  if (!cb) return promise;

  promise.then(res => cb(null, res), err => cb(err));
}

答案 1 :(得分:0)

您可以实现回调,然后使用pify模块添加承诺。

答案 2 :(得分:0)

您可以实现正常的CPS(延续传递样式)函数,并包含一个通用promisify函数,该函数使cps函数适应承诺返回函数。

function create (data, k) {
  db.insert(data, k)
}

function promisify (f) {
  return function (...args) {
    return new Promise (function (resolve, reject) {
      f (...args, function (err, result) {
        if (err)
          reject(err)
        else
          resolve(result)
      })
    })
  }
}

你可以像这样继续使用它

create (data, function(err, res) {
  if (err)
    // do something with the error
  else
    // do something with the result
})

或者你可以使用这样的承诺

promisify(create)(data)
  .then(res => {
    // do something with the result
  })
  .catch(err => {
    // do something with the error
  })

您会注意到create功能非常冗余。真的没有必要像这样包裹db.insert。相反,跳过创建create函数并像这样使用

// for cps, use normal api
db.insert(data, function(err, res) { ... })

// for promises, use the wrapper
promisify(db.insert)(data).then( ... )