Mehrere Punkte:
resolve
/reject
muss aufgerufen werden, da sonst ein new Promise()
wird für immer bleiben "offen".
- immer Promisify auf der niedrigsten möglichen Ebene, dh Promisify
db.each()
nicht getData()
. Dies gibt Ihnen ein testbares, wiederverwendbares Dienstprogramm und einen verständlicheren Anwendungscode.
db.each()
ist eine Herausforderung zu promisifizieren, weil es zwei mögliche Fehlerquellen hat; eine in ihrem Iterationsrückruf und eine in ihrem vollständigen Rückruf.
- Die sqlite3-Dokumentation gibt nicht an, was passiert, wenn ein Iterationsfehler auftritt, aber vermutlich wird die Iteration fortgesetzt, sonst erscheint der Fehler einfach als Abschlussfehler?
Hier ein paar Möglichkeiten promisify:
1. Erste Iterationsfehler oder Beendigung Fehlerursachen Ablehnung versprechen - Iteration Fehler werden in den Anwendungscode nicht ausgesetzt.
// Promisification
db.eachAsync = function(sql, iterationCallback) {
return new Promise(function(resolve, reject) {
db.each(sql, (iterationError, row) => {
if(iterationError) {
reject(iterationError);
} else {
iterationCallback(row);
}
}, (completionError, n) => {
if(completionError) {
reject(completionError);
} else {
resolve(n); // the number of retrieved rows.
}
});
});
};
// Application
app.get('/', (request, response) => {
function getData() {
var res = [];
return db.eachAsync('SELECT column_a, column_b FROM trips group by column_a', (row) => {
res.push({
a: row['column_a'],
b: row['column_b']
});
}).then(n => res);
}
getData().then(results => {
console.log(results);
}).catch(error => {
console.log(error);
});
});
2. Nur ein Abschluss Fehlerursachen versprechen Ablehnung - Iteration Fehler Anwendungscode ausgesetzt sind
// Promisification
db.eachAsync = function(sql, iterationCallback) {
return new Promise(function(resolve, reject) {
db.each(sql, iterationCallback, (completionError, n) => {
if(completionError) {
reject(completionError);
} else {
resolve(n); // the number of retrieved rows.
}
});
});
};
// Application
app.get('/', (request, response) => {
function getData() {
var res = [];
return db.eachAsync('SELECT column_a, column_b FROM trips group by column_a', (iterationError, row) => {
// You can choose what to do on iterationError.
// Here, nulls are injected in place of values from the db,
// but you might choose not to push anything.
res.push({
a: iterationError ? null : row['column_a'],
b: iterationError ? null : row['column_b']
});
}).then(n => res);
}
getData().then(results => {
console.log(results);
}).catch(error => {
console.log(error);
});
});
(2) ist der bessere Ansatz, da Fehler Iteration Aussetzen bietet Ihnen mehr Flexibilität . Zum Beispiel könnten Sie wählen, mit (2) und emulieren (1) in Ihrer Anwendung promisify:
// Application
app.get('/', (request, response) => {
function getData() {
var res = [];
var e = null;
return db.eachAsync('SELECT column_a, column_b FROM trips group by column_a', (iterationError, row) => {
if(iterationError && !e) {
// remember the first iteration error
e = iterationError;
} else {
// push only on success
res.push({
a: row['column_a'],
b: row['column_b']
});
}
}).then(n => {
if(e) {
throw e;
} else {
return res;
}
});
}
getData().then(results => {
console.log(results);
}).catch(error => {
console.log(error);
});
});
Mit (1), indem Sie auf dem ersten Iterationsfehler Ablehnung anstatt Iteration Fehler ausgesetzt wird, die gleiche Flexibilität ist Nicht verfügbar. (1) konnte nicht vollständig emulieren (2).
Glücklicherweise ist der bevorzugte Ansatz (2) ist das gleiche wie mit Bluebird .promisify()
Verfahren erhalten würde:
Promise.promisify(db.each);
Ich würde empfehlen, ein Versprechen-basierte Bibliothek wie 'Knoten-sqlite' oder' q-sqlite3 mit '(ist ein Versprechen Wrapper' sqlite3'), anstatt alle Funktionsaufrufe manuell zu wickeln. Es würde eine große Menge an Tipparbeit und Wartung sparen. – tcooc
können Sie eine Verknüpfung zu der node-sqlite-Bibliothek herstellen, auf die Sie sich beziehen? '' 'Npm install -g node-sqlite''' sagt' Registry hat 404 für GET unter http: // registry.npmjs.org/node-sqlite' zurückgegeben – Leahcim
https://www.npmjs.com/package/sqlite Betrachtet man es wieder, ist es nur ein Versprechen Wrapper um sqlite3 (ähnlich wie q-sqlite3, aber native Versprechen verwendet). – tcooc