2017-01-25 69 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)); 
}