【问题标题】:Transform a Promise based function into a sync one将基于 Promise 的函数转换为同步函数
【发布时间】:2017-06-19 17:41:20
【问题描述】:

我有一个函数,它从 npm 包 https://www.npmjs.com/package/get-port 返回一个承诺 getPort()

我需要更改这个,这样我就可以停止代码,直到我没有价值。喜欢:

var port = getPortSync()

我不能使用生成器或等待/异步,因为代码实际上不在函数中。

基本上,我想在节点中执行readFileSync 之类的操作。

我这样做的原因是我有一堆 mocha 测试,其中变量声明在文件顶部,我需要在这些变量的声明/初始化之前检索空闲端口值,我想要更改最小行数。

我目前的尝试是:

var getPortSync = function() {
  var port = null
    getPort().then(function(freePort) {
      console.log('port', freePort)
      port = freePort
    })
    while (port === null) {
      console.log('port: ', port)
    }
    return port
  }

【问题讨论】:

  • 两个问题:首先,为什么不直接在返回的 promise 的 then 内进行 Mocha 测试?第二,你的尝试成功了吗?
  • 对不起,我忘了说它不起作用。我只是为了说明我需要什么。

标签: javascript node.js promise mocha.js


【解决方案1】:

很遗憾,您的方法是不可能的。

那里的代码总是有一个无限循环,因为端口的分配是异步发生的,while 循环是一个同步构造。

如果你从包中打开代码,它获取端口的方式是通过异步回调:

server.listen(0, function () {
  var port = server.address().port;
  // ...
});

代码的主体部分server.address()只有在服务器发出listening事件后才会有端口信息,也就是说无法同步获取。

也许您可以将测试包装在 promise 的 then 中?

getPort().then((port) => {
  // your test code
});

您还可以使用 mocha 的测试钩子(与 Promise 配合得很好)在测试块之前获取端口:

describe('my-test', function() {

  let port;
  before(() => getPort().then((p) => {
    port = p;
  });

或者,如果您知道端口或者它始终相同,也许您可​​以在测试中对其进行硬编码。

【讨论】:

  • 你也可以坚守承诺。 let portPromise; before(() => portPromise = getPort())。然后,在您的测试中,您将从 portPromise.then((port) => { ... }) 开始。
  • 基本上,端口始终相同,但它用于启动服务器。所以现在我的测试如果你单独运行它们就可以工作,但如果你一起运行它们就不行!我们不希望使用随机数来避免冲突,也不希望每次测试都手动更改它们。您建议的方法(将代码移动到 .then 中)是我现在正在做的,但它很长,我试图找到一种方法来避免它:)
  • @jurgo 是的,不幸的是,您必须解决 javascript 的异步特性。 Async/await 可能会给出看起来最干净的代码,因为它看起来几乎是同步的,但由于你不能使用它,唯一的另一种方法是直接通过 Promise。
猜你喜欢
  • 2015-10-15
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 2015-06-25
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多