![](/img/trans.png)
[英]How do I delay an array callback using async/await in JavaScript?
[英]How do i wrap a callback with async await?
我的函数返回一个承诺,该承诺在 http 服务器启动后立即解决。 这是我的代码:
function start() {
return new Promise((resolve, reject) {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
}
如何将 start 函数转换为 async/await?
在函数声明之前包含async
并await
Promise
构造函数。 请注意,您实际上是在向现有模式添加代码。 await
将值转换为Promise
,尽管 Question 中的代码已经使用了Promise
构造函数。
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));
在这种情况下,像其他答案所建议的那样创建一个new Promise
工作正常,但作为一般规则, util.promisify可以阻止您多次编写相同的内容。
所以你可以做这样的事情:(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)
接受一个通常接受回调的函数,并返回此函数的新包装版本,而不是返回承诺。
有更多解释的步骤:
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);
更高级的promisification 可以用bluebird完成。
const doRequest = () => new Promise((resolve, reject) {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
async function start() {
await doRequest()
}
我相信这样的事情
这是我在尝试使http
服务器listen
功能真正承诺时偶然发现的。 最大的问题不是解决listening
回调,而是处理启动时的错误。
包装在 Promise 中并尝试catch
(如其他答案所建议的)或 try-catch 块不会产生任何效果,因为任何 Node.js 服务器、 net
或派生的http
/ https
都是EventEmitter
实例,这意味着不会引发错误。 相反,它们作为error
事件发出。
因此,考虑到以上所有因素,promisified server listen
功能的正确实现如下:
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);
});
}
处理程序中的拒绝和解决调用被添加到侦听器堆栈的顶部,并且它们相互抵消 - 谁先触发。
这样可以保证listen
方法要么启动服务器,要么抛出可捕获的错误。
我创建了一个基本的实用程序,它可能不是最合适的方法,但在 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;
}
这是基本概念。 但是,如果您的承诺可能返回未定义的值,则要小心,因为该函数将永远运行(但这不会崩溃)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.