Dialogflow-使用异步/等待

时间:2019-06-03 19:35:28

标签: node.js async-await dialogflow actions-on-google airtable

这是我第一次使用async / await。我在dialogflow意图内的数据库请求上下文中使用它时遇到问题。如何修复我的代码?

会发生什么?

当我尝试使用后端运行时-这就是我得到的:“ Webhook调用失败。错误:请求超时。”

我怀疑什么?

我的助手函数getTextResponse()等待airtable的返回值,但是从不获取它的值。

我想做什么?

  1. “ GetDatabaseField-Intent”被触发
  2. 在内部,它通过getTextResponse()向我的airtable数据库发送一个请求
  3. 因为我使用“ await”,所以该函数将等待结果,然后再继续
  4. getTextResponse()将返回“ returnData”;因此var结果将填充“ 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 个答案:

答案 0 :(得分:1)

正如@Kolban所指出的那样,您不接受或拒绝在from functools import wraps class Bar: def wrapper(self): def _outer(fun): @wraps(fun) def _f(*a, **kw): print('I am in decorator') return fun(*a, **kw) return _f return _outer def foo(): return Bar() # @foo().wrapper() # Invalid syntax # def f(): # pass # @(foo().wrapper()) # Invalid syntax # def f(): # pass def f(): pass f = foo().wrapper()(f) f() 中创建的承诺。

看起来getTextResponse()调用不正确。您已经定义了var result = await getTextResponse(...)来接受两个参数,但是您要传递三个参数(前两个参数以及一个匿名箭头函数)。但是,从未使用/引用此额外功能。

我通常会避免将显式的Promise与async / await混合使用,并且绝对要避免将async / await与传递的回调混合使用。

我不知道您使用的API的详细信息,但是如果API已经支持promise,那么您应该可以执行以下操作:

getTextResponse()

几乎所有基于承诺的库或API都可以与async / await一起使用,因为它们仅在后台使用Promises。 await 之后的所有内容都将成为一个回调,当等待的方法成功解析后,将调用该回调。任何不成功的解决方案都会引发PromiseRejected错误,您可以使用try / catch块进行处理。

答案 1 :(得分:0)

看代码,您似乎对JavaScript Promises产生了误解。创建Promise时,会传递两个名为resolve和reject的函数。在您的承诺代码的主体内(即将来会完成的代码)。您必须调用resolve(returnData)reject(returnData)。如果您不调用任何一个,那么您的Promise将永远无法实现。查看您的逻辑,您似乎正在执行简单的回报,而没有调用解决方案或拒绝。

让我再次向您询问有关JavaScript Promises的问题,并根据之前的评论再次进行研究,看看是否能解决这个难题。