2017-01-25 47 views
1

我不知道它可能是反模式。抽象函数为了让选择返回承诺或回调

很快,很年轻的开发人员会加入我们的开发团队,我想让他们选择是否要使用带回调或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); 
 
     
 
     }); 
 
    }); 
 
    } 
 
}

+0

我不一定称之为反模式。许多图书馆都是这样工作的但是,我会避免在同一代码库中混合使用承诺和回调,而不是让个别开发人员决定。如果你的新开发者对承诺不满意,他/她应该学习它们。 –

回答

0

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

0

您可以实现正常的CPS(continuation passing style)功能,并包含一个通用的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(...) 
1

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

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

...基本上,你返回一个承诺调用回调(如果一个通过)。因此,它可以用于任何一种方式。如果你不想采用蓝鸟,你基本上可以做同样的事情,像这样:

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

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