How do i wrap a callback with async await?

两盒软妹~` 提交于 2019-12-21 04:07:12

问题


My function resolves a promise that resolves as soon as the http server starts. This is my code:

function start() {
    return new Promise((resolve, reject) {
        this.server = Http.createServer(app);
        this.server.listen(port, () => {
            resolve();
        });
    })
}

How do i convert the start function to async/await?


回答1:


Include async before the function declaration and await the Promise constructor. Though note, you would essentially be adding code to the existing pattern. await converts a value to a Promise, though the code at Question already uses Promise constructor.

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



回答2:


Creating a new Promise like the other answers suggest works fine in this case, but as a general rule, util.promisify can stop you from writing the same thing many times.

So you can do something like this instead: (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) takes a function which normally accepts a callback, and returns a new, wrapped version of this function that instead returns a promise.

With more explained steps:

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

More advanced promisification can be done with bluebird.




回答3:


const doRequest = () => new Promise((resolve, reject) {
        this.server = Http.createServer(app);
        this.server.listen(port, () => {
            resolve();
        });
    })

async function start() {
 await doRequest()
}

something like this I believe




回答4:


This is something I've stumbled upon when while trying to make http server listen function truly promisified. Biggest problem is not to resolve on listening callback, but to handle the errors on startup.

Wrapping in Promise and attempt to catch (as other answers suggest) or try-catch block won't have any effect, because any Node.js server, net or derived http/https, are EventEmitter instances, which means no errors are thrown. Instead, they are emitted as the error event.

So, considering all of the above, correct implementation of promisified server listen function is as follows:

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

Reject and resolve calls inside handlers are prepended to the top of the listeners stack, and they mutually cancel each other - whoever fires first.

That way it's guaranteed that listen method will either start server or throw catchable error.




回答5:


I created a basic util that may not be the most proper way to do but is way more readable 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;
}

This is the basic concept. However be carreful if your promise may return undefined values has the function will run forever (but this will not crash).



来源:https://stackoverflow.com/questions/46933801/how-do-i-wrap-a-callback-with-async-await

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!