JS Promises等待函数并获取返回的对象

时间:2018-04-10 18:08:24

标签: javascript node.js es6-promise

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

  1. 使用mongoose连接到mongoDB
  2. 启动服务器(节点)
  3. 将一些测试数据直接添加到数据库中(通过猫鼬模型)
  4. //这个函数返回服务器实例,因为我需要在'之后' hook可以在测试执行后停止它。

    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函数的所有promise都被解析,你回到服务器实例并在开始插入数据之后数据库?这是一个虚拟的问题,但也有一些关于这个概念的更好解释的链接,我在这里将不胜感激。

    LE:整个问题已减少到以下几点:

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

    如何将callback转换为Promise并同时返回有效的server引用,以便最终我可以执行此操作:

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

1 个答案:

答案 0 :(得分:0)

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