抽象函数为了让select返回promise或callback
我不知道也许这是一个反模式。
很快,年轻的开发人员就会join我们的开发团队,我想让他们select是否要使用带有callback或Promises模式的模块。
这个function基本上把数据保存到数据库中。 我重复db.insertstream程来抽象函数,但有没有其他的方法来做到这一点?
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); }); }); } }
我喜欢蓝鸟.asCallback(…)方法:
function somethingAsync(cb) { return somePromise().asCallback(cb); }
…本质上,你返回一个承诺, 并调用callback(如果通过)。 因此,可以采用任何一种方式。 如果你不想采用蓝鸟,你基本上可以这样做:
function somethingAsync(cb) { var promise = somePromise(); if (!cb) return promise; promise.then(res => cb(null, res), err => cb(err)); }
你可以实现callback,然后使用pify
模块添加promise。
你可以实现正常的CPS(continuation passing style)function,并且包含一个通用的promisify
函数,用来使cps函数适应promise函数。
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
function是相当多余的寿。 真的不需要像这样包装db.insert
。 相反,跳过创buildcreate
function,只是这样使用
// for cps, use normal api db.insert(data, function(err, res) { ... }) // for promises, use the wrapper promisify(db.insert)(data).then( ... )