Node.js 和 Express:在响应 HTTP 请求之前等待异步操作

Ale*_*der 3 javascript node.js promise express async-await

假设有一个 HTTP GET 回调定义为:

router.get('/latestpost', function(req, res, next) {

    var data = new FbData();
    get_latest_post (data);
    get_post_image (data);

    res.json(data);
};
Run Code Online (Sandbox Code Playgroud)

这两个get_函数都使用fb 包生成 HTTP 请求并在完成后执行回调。如何修改上述 GET 回调以便等待 Facebook 的响应,然后才向客户端发送响应?

当时,我通过get_串联执行函数并向它们传递res(响应)参数来解决问题,最后一个函数发送响应:

router.get('/latestpost', function(req, res, next) {
    var data = new FbData();
    get_latest_post (res, data);
};


function get_latest_post (res, data) {

    FB.api(_url, function (res_fb) {

        if(!res_fb || res_fb.error) {
            console.log(!res_fb ? 'error occurred' : res_fb.error);
            return;
        }

        // Do stuff with data

        get_post_image (res, data);
    });
}


function get_post_image (res, data) {

    FB.api(_url, function (res_fb) {

        if(!res_fb || res_fb.error) {
            console.log(!res_fb ? 'error occurred' : res_fb.error);
            return;
        }

        // Do stuff with data

        /* At the end send the post data to the client */
        res.json(data);
    });
}
Run Code Online (Sandbox Code Playgroud)

我发现了一个类似的问题,但我正在思考它,因为我找不到正确的方法来将解决方案应用于我的问题。我尝试过使用本手册中描述的模式,但我无法使用 Promise 或 async/await 来执行它。有人可以指出我正确的方向吗?

Jon*_*lms 6

您的 API 可以轻松修改以返回承诺:

 function get_post_image (res, data) {
   return new Promise((resolve, reject) => {
    FB.api(_url, function (res_fb) {
      if(!res_fb || res_fb.error) {
        reject(res_fb && res_fb.error);
      } else resolve(res_fb/*?*/);
   });
 }
Run Code Online (Sandbox Code Playgroud)

现在你有了一个承诺,你可以等待它:

 router.get('/latestpost', async function(req, res, next) {
   const data = new FbData();
   const image = await get_post_image (data);

   res.json(data);
});
Run Code Online (Sandbox Code Playgroud)

  • 最好将“await”包装在“try”中,并将捕获的错误传递给“next()”,这样就不会出现未捕获的被拒绝的承诺。但您不能使用 util.callbackify() ,因为它会在成功时调用带有两个参数的 next() ,这是不希望的。 (2认同)