【问题标题】:JS Promises wait for the function and get the returned objectJS Promises 等待函数并获取返回的对象
【发布时间】:2018-04-14 21:59:37
【问题描述】:

我正在尝试构建一些测试辅助函数,这些函数将帮助我使用Mocha 运行一些挂钩来测试我的 GraphQL 查询(只要您了解上下文)。 我想在每次运行测试之前执行以下步骤:

  1. 使用 mongoose 连接到 mongoDB
  2. 启动服务器(节点)
  3. 将一些测试数据直接添加到数据库中(通过猫鼬模型)

// 这个函数返回服务器实例,因为我需要它在 'after' 钩子中以便能够在测试执行后停止它。

export const startServer = () => {
  mongoose.Promise = global.Promise;
  mongoose.connect(MONGO_URI_TEST);
  return mongoose.connection.once('open', () => {
    const app = express();
    app.post('/graphql', bodyParser.json(), graphqlExpress(req => {
      return { schema: executableSchema };
    })
    );
    return app.listen(9000, () => {
      console.log('Server started!');
    });
  });
};

// now here's the before hook where the server is started
let server;
before( done => {
  server = startServer(done); // here I need to wait 
  // some other async code that inserts test data into mongo
  const user = new User({email: test@test.com});
  user.save().then(() => {
    // saved successfully
    done();
  })
});

我是 JS 世界的新手,你如何设法等待(没有异步等待语法),直到 startServer 函数的所有承诺都得到解决,你取回服务器实例,然后开始将数据插入数据库?这是一个愚蠢的问题,但我在这里提供的一些链接可以更好地解释这个概念,我们将不胜感激。

LE:整个问题已简化为以下内容:

const createServer = () => {
const server = app.listen(port, () => {
  //callback body here
  });
};

如何将callback 转换为Promise 并同时返回一个有效的server 引用,以便最终我可以这样做:

const someOtherFunction = () => {
  createServer().then(myValidServerInstance => {
    //do something with that instance
  }
}

【问题讨论】:

  • once() 返回什么?如果你想使用 Promise,我猜你不应该传递回调。
  • 你能用async/await管理它吗?如果是,请告诉我们您尝试使用它,如果不是,您为什么不想使用它?
  • 声明here,“为事件添加一次性侦听器。此侦听器仅在下一次触发事件时调用,之后将其删除。返回对 EventEmitter 的引用,这样调用就可以被链接起来。”。无论如何,我想我找到了解决方案,使用 mongoose.connect 返回的 Promise。我会回复是否有效。
  • 是的,如果.connect() 确实返回了一个promise,那将比once 返回的事件发射器更适合使用。
  • @Bergi:我已经编辑了这个问题。我使用了 connect() 和 Promise 机制。

标签: javascript node.js es6-promise


【解决方案1】:

TLDR:关于 JS Promises 的一些事情我并不清楚,例如通过resolve() 方法返回结果。

所以正确答案是这样的:

export const startServer = () => {
  mongoose.Promise = global.Promise;
// first mistake was the use of callbacks rather than Promise approach offered by mongoose.connect
  return mongoose.connect(MONGO_URI_TEST).then(() => {
    console.log('Connected to MongoLab TEST instance.');
    return createServer();
  },
  err => {
    console.log('Error connecting to MongoLab TEST instance:', err);
  });
};

第二个是在操作完成之前直接返回listen()的结果。因此,我将启动服务器的代码移到了另一种方法中,并将 listen() 的结果包装到一个 Promise 中,并仅在服务器实际开始侦听时才解析该 Promise。

const createServer = () => {
  const app = express();
  app.post('/graphql', bodyParser.json(), graphqlExpress(req => {
    return {
      schema: executableSchema,
      context: { headers: req.headers},
    };
  })
  );
  return new Promise((resolve, reject) => {
    const server = app.listen(9000, () => {
      if (server) {
        console.log('Server started on port 9000');
        resolve(server);
      } else {
        reject();
      }
    });
  });
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    相关资源
    最近更新 更多