2017-01-25 4 views
1

Ich weiß nicht, vielleicht ist es ein Antipattern.Abstrakte Funktion, um wählen zu lassen Versprechen oder Rückruf

Bald werden sehr junge Entwickler unserem Entwicklerteam beitreten, und ich möchte sie entscheiden lassen, ob sie das Modul mit Callback oder Promises-Muster verwenden wollen.

Diese Funktion speichert grundsätzlich Daten in der Datenbank. Ich wiederhole den db.insert-Ablauf, um die Funktion zu abstrahieren, aber gibt es einen anderen Weg, dies zu tun?

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

Ich würde es nicht unbedingt ein Anti-Muster nennen. Viele Bibliotheken arbeiten auf diese Weise. Ich würde jedoch vermeiden, Versprechen und Rückrufe innerhalb der gleichen Codebasis zu mischen, anstatt einzelne Entwickler entscheiden zu lassen. Wenn dein neuer Entwickler sich nicht mit Versprechungen zufrieden gibt, sollte er/sie sie lernen. –

Antwort

0

Sie können nur den Rückruf implementieren und verwenden Sie dann den pify Modul, das Versprechen hinzuzufügen.

0

Sie könnten einfach die normale CPS-Funktion (Continuation Passing Style) implementieren und eine generische promisify-Funktion einschließen, die cps-Funktionen an Funktionen mit Versprechensrückkehr anpasst.

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) 
     }) 
    }) 
    } 
} 

Sie können es mit der Fortsetzung verwenden wie dieses

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

Oder Sie können Versprechen verwenden wie dieses

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

werden Sie feststellen, dass die create Funktion ziemlich überflüssig tho ist. Es gibt wirklich keine Notwendigkeit, die db.insert so zu wickeln. Stattdessen lassen Sie die create Funktion erstellen und nur beide verwenden wie diese

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

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

ich die drossel .asCallback(...) Ansatz mag:

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

... im Wesentlichen, kehren Sie ein Versprechen und Anruf ein Rückruf (wenn man bestanden wurde). Daher kann es in beide Richtungen verwendet werden. Wenn Sie Bluebird nicht adoptieren möchten, können Sie im Wesentlichen das gleiche tun:

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

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