Dialogflow - чтение из базы данных с использованием async / await - PullRequest
1 голос
/ 03 июня 2019

я впервые использую async / await. У меня есть проблемы, чтобы использовать его в контексте запроса к базе данных внутри намерения диалогового потока. Как я могу исправить свой код?

Что происходит?

Когда я пытаюсь запустить, использую свой бэкэнд - вот что я получаю: «Сбой вызова Webhook. Ошибка: истекло время ожидания».

Что я подозреваю?

Моя вспомогательная функция getTextResponse () ожидает возвращаемого значения airtable, но никогда не получает его.

Что я хочу сделать?

  1. "GetDatabaseField-Intent" запускается
  2. Внутри он отправляет запрос в мою базу данных по расписанию через getTextResponse ()
  3. Поскольку я использую «ожидание», функция будет ожидать результата, прежде чем продолжить
  4. getTextResponse () вернет «returnData»; поэтому результат будет заполнен значением returnData
  5. getTextResponse () завершен; поэтому ответ будет создан с возвращаемым значением
'use strict';

const {
  dialogflow
} = require('actions-on-google');

const functions = require('firebase-functions');
const app = dialogflow({debug: true});
const Airtable = require('airtable');
const base = new Airtable({apiKey: 'MyKey'}).base('MyBaseID');

///////////////////////////////
/// Helper function - reading Airtable fields.
const getTextResponse = (mySheet, myRecord) => {
    return new Promise((resolve, reject) => {
        // Function for airtable
        base(mySheet).find(myRecord, (err, returnData) => {
        if (err) {
            console.error(err);
            return; 
        }
        return returnData;
        });
    }       
)};

// Handle the Dialogflow intent.
app.intent('GetDatabaseField-Intent', async (conv) => {
  const sheetTrans = "NameOfSheet";
  const recordFirst = "ID_OF_RECORD";

  var result = await getTextResponse(sheetTrans, recordFirst, (callback) => {
    // parse the record => here in the callback
    myResponse = callback.fields.en;

  });
  conv.ask(myResponse);
});

// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Как отметил @Kolban, вы не принимаете и не отклоняете обещание, которое создаете в getTextResponse().

Похоже, что var result = await getTextResponse(...) вызов неверен. Вы определили getTextResponse() для приема двух параметров, но передаете их три (первые два плюс функция анонимной стрелки). Но эта дополнительная функция никогда не используется / ссылается.

Я бы вообще не смешивал явные обещания с async / await и определенно избегал бы смешивания async / await с передачей обратных вызовов.

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

const getTextResponse = async (mySheet, myRecord) => {
    try {
        return await base(mySheet).find(myRecord)
    }
    catch(err) {
        console.error(err);
        return; 
    }
)};

...

app.intent('GetDatabaseField-Intent', async (conv) => {
  const sheetTrans = "NameOfSheet";
  const recordFirst = "ID_OF_RECORD";

  var result = await getTextResponse(sheetTrans, recordFirst)
  myResponse = result.fields.en;
  conv.ask(myResponse);
});

...

Почти все обещанные основанные библиотеки или API могут использоваться с async / await, поскольку они просто используют Promises под капотом. Все после await становится обратным вызовом, который вызывается, когда ожидаемый метод разрешается успешно. При любом неудачном разрешении возникает ошибка PromiseRejected, которую вы обрабатываете с помощью блока try / catch.

0 голосов
/ 03 июня 2019

Глядя на код, кажется, что у вас может быть неправильное понимание обещаний JavaScript. Когда вы создаете Обещание, вам передаются две функции, которые называются разрешить и отклонить. В теле вашего кода обещания (то есть кода, который завершится когда-нибудь в будущем). Вы должны вызвать либо resolve(returnData), либо reject(returnData). Если вы тоже не призовете, ваше Обещание никогда не будет выполнено. Глядя на свою логику, вы, похоже, выполняете простые возвраты, не вызывая решимости или отклонения.

Позвольте мне снова попросить вас посетить Google Обещания JavaScript и изучить их снова в отношении только что сделанных предыдущих комментариев и посмотреть, не прояснит ли это загадку.

...