Meine Funktion löst ein Versprechen auf, das gelöst wird, sobald der http-Server gestartet wird. Das ist mein Code:
function start() {
return new Promise((resolve, reject) {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
}
Wie kann ich die Startfunktion in asynchron/warten konvertieren?
Fügen Sie async
vor der Funktionsdeklaration und await
den Promise
-Konstruktor ein. Beachten Sie jedoch, dass Sie im Wesentlichen dem vorhandenen Muster Code hinzufügen. await
konvertiert einen Wert in eine Promise
, obwohl der Code in Question Promise
-Konstruktor bereits verwendet.
async function start() {
let promise = await new Promise((resolve, reject) => {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
.catch(err => {throw err});
return promise
}
start()
.then(data => console.log(data))
.catch(err => console.error(err));
Wenn Sie einen new Promise
wie die anderen Antworten erstellen, ist dies in diesem Fall gut, aber in der Regel kann util.promisify Sie verhindern, dass Sie dasselbe oft schreiben.
So können Sie stattdessen etwas tun: (node.js v8.0.0 +)
const util = require('util');
async function start() {
let server = Http.createServer(app);
await util.promisify(server.listen.bind(server))(port);
}
util.promisify(some_function)
nimmt eine Funktion, die normalerweise einen Rückruf akzeptiert, und gibt eine neue, umschlossene Version dieser Funktion zurück, die stattdessen ein Versprechen zurückgibt.
Mit mehr erklärten Schritten:
let server = Http.createServer(app);
// .bind() is needed so that .listen() keeps the correct `this` context when it is called.
// If your function does not require any specific context, leave off .bind()
let listen_promise = util.promisify(server.listen.bind(server));
await listen_promise(port);
Weitergehende Versprechungen können mit bluebird durchgeführt werden.
const doRequest = () => new Promise((resolve, reject) {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
async function start() {
await doRequest()
}
so etwas glaube ich
Dies ist etwas, worüber ich gestolpert bin, als ich versuche, die http
server listen
-Funktion wirklich zu versprechen. Das größte Problem besteht nicht darin, listening
callback zu lösen, sondern die Fehler beim Start zu behandeln.
Das Umwickeln in Promise und der Versuch, catch
(wie andere Antworten vermuten lassen) oder Try-Catch-Block haben keine Auswirkungen, da alle Server, net
oder abgeleiteten http
/https
-Instanzen EventEmitter
sind. Sie werden stattdessen als error
-Ereignis ausgegeben.
In Anbetracht all der obigen Punkte lautet die korrekte Implementierung der listen
-Funktion des zugesagten Servers wie folgt:
const { createServer } = require('http');
const server = createServer();
const listen = async (port, Host) => {
return new Promise((resolve, reject) => {
const listeners = {};
listeners.onceError = (error) => {
server.removeListener('listening', listeners.onceListening);
reject(error);
};
listeners.onceListening = () => {
server.removeListener('error', listeners.onceError);
resolve();
};
server
.prependOnceListener('error', listeners.onceError)
.prependOnceListener('listening', listeners.onceListening);
server.listen(port, Host);
});
}
Ablehnungs- und Auflösungsaufrufe innerhalb von Handlern werden dem Listener-Stack vorangestellt und stornieren sich gegenseitig - wer zuerst feuert.
Auf diese Weise wird garantiert, dass die listen
-Methode den Server startet oder einen abfangbaren Fehler ausgibt.
Ich habe eine grundlegende Funktion erstellt, die möglicherweise nicht die geeignetste Methode ist aber so besser lesbar IMO:
// async timout util
const timeout = async ms => new Promise(res => setTimeout(res, ms));
async function start() {
let output;
this.server = Http.createServer(app);
this.server.listen(port, () => {
output = true; // or can be any data that you want to return
});
while (output === undefined) await timeout(10);
return output;
}
Dies ist das Grundkonzept. Sei jedoch carreful Wenn dein Versprechen undefinierte Werte zurückgibt, wird die Funktion für immer ausgeführt (dies wird jedoch nicht abstürzen).