Экспресс-маршрутизатор ожидает условной функции перед отправкой ответа

Я создаю приложение Express с помощью Twilio, чтобы группа людей могла общаться с помощью SMS без необходимости устанавливать приложение или иметь дело с ограничениями на групповые тексты, которые, по-видимому, есть у некоторых телефонов/операторов. Он развернут через Azure, но я уверен, что избавился от головной боли с настройкой. В качестве первого теста, который я могу заставить это работать, и для небольшого вкуса, я пытаюсь настроить функцию, чтобы вы могли написать «шутка» (в идеале без учета регистра), и она отправит случайную шутку из https://icanhazdadjoke.com/. Если что-то еще отправлено в текстовом сообщении, на данный момент это должно быть отражено в ответ.

Я понимаю, что это связано с тем, что js является асинхронным, и код перемещается до того, как GET вернется, поэтому я пытаюсь использовать промисы, чтобы заставить код ждать, но условный характер - это новая морщина для меня. Я искал ответы, но ничего не работает. Я, по крайней мере, изолировал проблему, чтобы рука без шуток работала правильно.

Вот функция получения шутки, console.log выводит правильно:

const rp = require('request-promise-native');
var options = {
    headers: {
        'Accept': 'application/json'
    }
}
function getJoke() {
    rp('https://icanhazdadjoke.com/', options) //add in headers
    .then(joke => {
        theJoke = JSON.parse(joke).joke
        console.log(theJoke)
        return theJoke
    });
}
}

Вот часть моего маршрутизатора, которая работает не совсем правильно. Если я напишу что-то, что не является «шуткой», я получу ответ в виде SMS. Если я напишу "шутка", мне не приходит ответное СМС, я вижу "undefined" в логе Kudu (снизу), потом вижу лог POST, а потом уже вижу шутку от функции выше пробежав.

smsRouter.route('/')
.post((req, res, next) => {
    const twiml = new MessagingResponse();
    function getMsgText(request) {
      return new Promise(function(resolve, reject) {
        if (req.body.Body.toLowerCase() == 'joke') {
          resolve(getJoke());
        }
        else {
          resolve('You texted: ' + req.body.Body);
        }
      })
    }
    getMsgText(req)
    .then(msg => {
      console.log(msg);
      twiml.message(msg);
      res.writeHead(200, {'Content-Type': 'text/xml'});
      res.end(twiml.toString());
    })
  })

Как я могу сделать так, чтобы getMsgText() ждал полного разрешения вызова getJoke(), прежде чем перейти к .then?


person Tristan Markwell    schedule 09.05.2019    source источник
comment
Я бы использовал async/await для упрощения кода. Приложу решение через секунду   -  person Aviad    schedule 10.05.2019


Ответы (1)


Я думаю, это то, что вы ищете. Обратите внимание, что я использовал async/await, а не цепочку промисов.

// joke.get.js
const rp = require('request-promise-native');
var options = {
    headers: {
        'Accept': 'application/json'
    }
}
async function getJoke() {
    const data = await rp('https://icanhazdadjoke.com/', options) //add in headers
    return JSON.parse(data).joke;
}



// route.js
smsRouter.route('/')
.post(async (req, res, next) => {
    const twiml = new MessagingResponse();
    async function getMsgText(request) {
      if(req.body.Body.toLowerCase() === 'joke'){
        return await getJoke();
      }
      return `You texted: ${req.body.Body}`
    }

    const msg = await getMsgText(req);
    twiml.message(msg);
    res.status(200).send(twiml.toString());
  })

async/await в JS

person Aviad    schedule 10.05.2019
comment
Есть ли причина, по которой цепочка обещаний здесь не работает? У меня сложилось впечатление, что разные способы ожидания ответа были эквивалентны, но просто отличались синтаксисом, поэтому я сосредоточился на изучении только цепочки промисов, потому что это было то, на чем были написаны мои учебники, и потому что это выглядит наиболее элегантно для меня. . Кроме того, есть ли причина, по которой нужны все три await - это просто тот случай, когда вам нужно await на всем пути вверх по цепочке, чтобы он использовал специальное поведение ожидания, потому что это не стандарт? - person Tristan Markwell; 10.05.2019
comment
Цепочка промисов здесь отлично сработает, async облегчает нашу жизнь в этом вопросе. Что касается awaits - await мы ждем разрешения. Я всегда хотел убедиться, что мой ;) - person Aviad; 11.05.2019