如何等待直到回调被调用

时间:2018-12-23 02:53:24

标签: node.js koa async.js

我有一个执行长时间计算的函数,完成后将调用作为参数传递的回调函数。 我在Koa路由器中查询此功能,需要将长时间计算的结果返回给浏览器。函数来自库,我无法更改其接口(即,我可以更改回调的代码,但不能更改someLongComputation以返回承诺)

ctx.body立即返回时,当前代码立即设置someLongComputation。我不知道如何才能等到回调被调用,然后才用回调的结果设置ctx.body

router.post(`/abc`, async (ctx) => {
  try {
      someLongComputation(function(err, res) {
          if(err) {
              console.log(err);
          }
      }
      ctx.body = {
        status: 'success',
        data: {'res' : ""}, 
        errors: []
      };
  } catch (err) {
      console.log(err)
  }
})

2 个答案:

答案 0 :(得分:2)

如果要使用async / await并假设longcomputation函数可以返回promise,则可以更改代码以等待该函数的返回。

router.post(`/abc`, async (ctx) => {
  try {
    const result = await someLongComputation();
    // do whatever you want with result

  } catch (err) {
    console.log(err)
  }
})

另一种选择是在函数的回调中使用变量

router.post(`/abc`, async (ctx) => {
  try {
    someLongComputation(function(err, res) {
      if(err) {
          console.log(err);
      }
      //moved setting the body to inside the callback for the computation
      ctx.body = {
        status: 'success',
        data: {'res' : ""}, 
        errors: []
      };
    }
  } catch (err) {
    console.log(err)
  }
})

答案 1 :(得分:1)

您有两个选择。

1。通过回调发送响应

router.post(`/abc`, async (ctx) => {
  try {
    someLongComputation(function(err, res) {
      if (err) {
        console.log(err);
        // you might want to send error response here
      }
      // send response from callback
      ctx.body = {
        status: 'success',
        data: { res: '' },
        errors: []
      };
    });
  } catch (err) {
    console.log(err);
    // you might want to send error response here as well
  }
});

2。利用您的库函数创建一个Promise,并使用async/await

const doLongComputation = () => {
  return new Promise((resolve, reject) => {
    try {
      someLongComputation(function(err, res) {
        if (err) {
          console.log(err);
          reject(err);
        }
        resolve(res);
      });
    } catch (err) {
      console.log(err);
      reject(err);
    }
  });
};

router.post(`/abc`, async (ctx) => {
  try {
    const res = await doLongComputation();
    ctx.body = {
      status: 'success',
      data: { res: '' },
      errors: []
    };
  } catch (err) {
    console.log(err);
    // send error response here
  }
});