javascript - 无法获取 promise 函数的原始返回值

标签 javascript node.js express asynchronous promise

下面的代码可以工作,但没有 promise 。

const express = require('express');
function listenAndReturnServer() {
    app = express();

    console.log('Before listen');
    const server = app.listen(8001, function() {
        console.log('Now listening');
    });
    console.log('After listen');
    return server;
}
const server = listenAndReturnServer();
console.log('Doing some stuff');
console.log(typeof(server));

它输出以下内容:

Before listen
After listen
Doing some stuff
object
Now listening

我试图解决的问题是我想用依赖于服务器运行的代码替换“做一些事情”日志,并且监听回调(打印“正在监听”)已被调用。正如您所看到的,“做一些事情”记录在“正在收听”之前。 util.promisify 来了。

我已将上面的内容更改为以下内容。

const express = require('express');
const util = require('util');
async function listenAndReturnServer() {
    app = express();

    console.log('Before listen');
    const listenAsync = util.promisify(app.listen);
    const server = await listenAsync(8001).then(() => {
        console.log('Now listening');
    });
    console.log('After listen');
    return server;
}
async function main() {
    const server = await listenAndReturnServer();
    console.log('Doing some stuff');
    console.log(typeof(server));
}
main();

这一次,事情至少以正确的顺序记录。

Before listen
Now listening
After listen
undefined
Doing some stuff

现在有一个新问题:server的类型未定义。我实际上需要它作为原始的 Server 对象,这样我就可以关闭服务器。

任何人都可以确定这里发生了什么,以及我如何获得我想要的行为?

最佳答案

[重写,因为这里发生了很多事情]

在对这段代码进行了一些研究之后,我意识到存在几个问题/错误的假设,如下所示:

const express = require('express');
const util = require('util');
async function listenAndReturnServer() {
    app = express();

    console.log('Before listen');

// ISSUE #1: `listenAsync` is not bound to `app` here.  This
// risks errors where Express may rely on `this` internally.
//
// ISSUE #2: Promisify is intended to operate on methods that
// take node-style callbacks, where the *callback* receives
// (err, arg0, arg1, ...) arguments, with the promise
// resolving to the 2nd argument (arg0).
// In the case of listen(), though, the callback isn't expected
// to be node-style(!), so doesn't receive any arguments
// (see https://nodejs.org/api/net.html#net_server_listen)
    const listenAsync = util.promisify(app.listen);

// ISSUE #3: `await` and `then()` serve similar purposes.
// Using them together like this is a little weird.
// You should probably just `await`, then do your console.log
// afterwards.      
    const server = await listenAsync(8001).then(() => {
        console.log('Now listening');
    });
    console.log('After listen');
    return server;
}
async function main() {
    const server = await listenAndReturnServer();
    console.log('Doing some stuff');
    console.log(typeof(server));
}
main();

如果您想 Promisify 使其与 async 一起工作,那么创建一个 Promise 可能会更简单:

const express = require('express');

const app = express();

// Note: Not writing this as an `async` function because none
// of the APIs we're using return promises that can be `await`ed,
// and we explicitly return a promise
function main() {
  return new Promise(function(resolve, reject) {
    // Resolve to the server instance if listen() succeeds
    // Note: `server` here is Node's `http` server, not the Express instance
    const server = app.listen(8001, () => resolve(server));

    // Otherwise reject promise if there's an error
    server.on('error', reject);
  });
}

main()
  .then(server => console.log(server))
  .catch(err => console.error(err));

关于javascript - 无法获取 promise 函数的原始返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54795136/

相关文章:

JavaScript - 如何以编程方式计算颜色?

javascript - 如何在 node.js 的客户端包含 javascript?

javascript - 在选择提交时重定向到值 url

javascript - 将 JavaScript 函数分配给变量的效果

node.js - 在 Node 7.4 中使用 async/await

node.js - 无法上传多个文件

javascript - 获取 "message":"Admin validation failed" Mongoose 、node.js 中的错误

node.js - 如何在 nwjs 中包含 node-sass(在 Windows 上)

node.js - socket.on 没有监听事件

javascript - Mongoose Delete 和 Express app.delete 有什么区别