Actions on google 对谷歌v1的行动->;v2迁移:“;错误:已发送响应";

Actions on google 对谷歌v1的行动->;v2迁移:“;错误:已发送响应";,actions-on-google,Actions On Google,我正在从v1迁移到v2 alpha,出现以下错误: Error: Response has already been sent. Is this being used in an async call that was not returned as a promise to the action/intent handler? at DialogflowConversation.add (/user_code/node_modules/actions-on-google/dist/servic

我正在从v1迁移到v2 alpha,出现以下错误:

Error: Response has already been sent. Is this being used in an async call that was not returned as a promise to the action/intent handler?
at DialogflowConversation.add (/user_code/node_modules/actions-on-google/dist/service/actionssdk/conversation/conversation.js:51:19)
at DialogflowConversation.close (/user_code/node_modules/actions-on-google/dist/service/actionssdk/conversation/conversation.js:66:21)
at Request.err [as _callback] (/user_code/index.js:1141:20)
at Request.self.callback (/user_code/node_modules/request/request.js:186:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/request/request.js:1163:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/user_code/node_modules/request/request.js:1085:12)
代码位置:

我不明白为什么会出现上述错误,到目前为止我还没有向用户发送响应。对外部REST API的请求(使用请求库)可能被视为“响应”,可能导致此错误

可能是conv.close()元素中简单响应的格式

知道为什么会发生这种错误吗

干杯


编辑:

我想我需要开始使用异步代码&像这个v2代码段这样的承诺吗?在REST API查询开始之前,它似乎为空

app.intent('tell_greeting', conv => {
  // Return a promise to do async asks, will send everything when promise     resolves
  return new Promise(resolve => setTimeout(() => resolve(), 1000))
    .then(() => {
      conv.ask('Hi')
    })
})

为了鼓励最佳实践,v2客户端库需要使用承诺来执行异步请求

响应生成的工作原理是,它将在
IntentHandler
函数执行结束时生成并发送响应,除非函数返回
Promise
,然后它将等待
Promise
解析,然后发送响应

您可以查看v2.0.0-alpha分支中包含的,以查看一个工作示例:

app.intent('handle_permission',(conv,params,permissiongrated)=>{
// ...
返回坐标城市(坐标.纬度,坐标.经度)
.然后(城市=>{
conv.user.storage.location=城市
屏幕上显示位置(conv)
})
// ...
}
协调城市
这里有一个函数,它返回一个
承诺

showLocationOnScreen
这是一个调用
conv.ask
conv.close
并生成响应的函数

const showLocationOnScreen=conv=>{
const capability='actions.capability.SCREEN\u输出'
if(conv.surface.capabilities.has(capability)||
!conv.available.surfaces.capabilities.has(capability)){
返回conv.close(…responses.sayLocation(conv.user.storage.location))
}
conv.ask(新的新闻界面)({
上下文:responses.newSurfaceContext,
通知:responses.notificationText,
能力:能力,,
}))
}
如果您的Node.js版本支持async await(我认为默认情况下启动Node.js 7.6+,但为了安全起见,请使用Node.js 8+),那么您可以简化代码,使其不连锁
。然后

app.intent('handle_permission',异步(conv,params,permissiongrated)=>{
// ...
const city=等待坐标城市(坐标.纬度,坐标.经度)
conv.user.storage.location=城市
返回显示屏幕上的位置(conv)
// ...
}

请注意,Firebase函数当前使用Node.js 6,而当前不支持async Wait,因此您需要一个transpiler在其中使用它。

为了鼓励最佳实践,v2客户端库需要使用承诺来执行异步请求

响应生成的工作原理是,它将在
IntentHandler
函数执行结束时生成并发送响应,除非函数返回
Promise
,然后它将等待
Promise
解析,然后发送响应

您可以查看v2.0.0-alpha分支中包含的,以查看一个工作示例:

app.intent('handle_permission',(conv,params,permissiongrated)=>{
// ...
返回坐标城市(坐标.纬度,坐标.经度)
.然后(城市=>{
conv.user.storage.location=城市
屏幕上显示位置(conv)
})
// ...
}
协调城市
这里有一个函数,它返回一个
承诺

showLocationOnScreen
这是一个调用
conv.ask
conv.close
并生成响应的函数

const showLocationOnScreen=conv=>{
const capability='actions.capability.SCREEN\u输出'
if(conv.surface.capabilities.has(capability)||
!conv.available.surfaces.capabilities.has(capability)){
返回conv.close(…responses.sayLocation(conv.user.storage.location))
}
conv.ask(新的新闻界面)({
上下文:responses.newSurfaceContext,
通知:responses.notificationText,
能力:能力,,
}))
}
如果您的Node.js版本支持async await(我认为默认情况下启动Node.js 7.6+,但为了安全起见,请使用Node.js 8+),那么您可以简化代码,使其不连锁
。然后

app.intent('handle_permission',异步(conv,params,permissiongrated)=>{
// ...
const city=等待坐标城市(坐标.纬度,坐标.经度)
conv.user.storage.location=城市
返回显示屏幕上的位置(conv)
// ...
}
请注意,Firebase函数当前使用Node.js 6,而当前不支持async Wait,因此您需要一个transpiler在那里使用它

app.intent('tell_greeting', conv => {
  // Return a promise to do async asks, will send everything when promise     resolves
  return new Promise(resolve => setTimeout(() => resolve(), 1000))
    .then(() => {
      conv.ask('Hi')
    })
})