Как дождаться звонка - PullRequest
       9

Как дождаться звонка

0 голосов
/ 23 декабря 2018

У меня есть функция, которая выполняет длительные вычисления, и после ее завершения вызывает функцию обратного вызова, которая передается в качестве параметра.Я запрашиваю эту функцию в роутере 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 голосов
/ 23 декабря 2018

У вас есть два варианта.

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.Создайте обещание из вашей библиотечной функции и используйте 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
  }
});
0 голосов
/ 23 декабря 2018

Если вы хотите использовать async / await и предполагать, что функция longcomputation может вернуть обещание, вы можете изменить свой код, чтобы дождаться возврата функции.

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)
  }
})
...