我从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)
来源:
try {
conv.close(new SimpleResponse({
// Sending the details to the user
speech: textToSpeech1,
text: displayText1
}))
} catch (err) {
if(err instanceof Error) {
console.error(err);
} else {
console.error(new Error(err));
}
}
代码位置:https://github.com/BTS-CM/BeyondBitshares-Firebase/blob/master/index_v2.js#L1141
我不明白为什么我会收到上述错误,我还没有向用户发送回复。也许对外部REST API的请求(使用请求库)可以被视为“响应”。可能导致这个错误?
也许它是conv.close()元素中简单响应的格式?
知道为什么会出现这种错误吗?
干杯
编辑:
认为我需要开始使用异步代码&amp;承诺像这个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')
})
})
答案 0 :(得分:2)
为了鼓励最佳实践,v2客户端库需要使用Promises来执行异步请求。
响应生成的工作原理是它将在IntentHandler
函数执行结束时生成并发送响应,除非函数返回Promise
,然后它将等到{{1}然后解析然后发送响应。
您可以查看v2.0.0-alpha分支中包含的Name Psychic sample以查看工作示例:
Promise
app.intent('handle_permission', (conv, params, permissionGranted) => {
// ...
return coordinatesToCity(coordinates.latitude, coordinates.longitude)
.then(city => {
conv.user.storage.location = city
showLocationOnScreen(conv)
})
// ...
}
这是一个返回coordinatesToCity
。
Promise
这是一个调用showLocationOnScreen
或conv.ask
并生成回复的函数。
conv.close
如果您的Node.js版本支持异步等待(我认为默认情况下启动Node.js 7.6+,但为了安全使用Node.js 8+),那么您可以简化代码以不链const showLocationOnScreen = conv => {
const capability = 'actions.capability.SCREEN_OUTPUT'
if (conv.surface.capabilities.has(capability) ||
!conv.available.surfaces.capabilities.has(capability)) {
return conv.close(...responses.sayLocation(conv.user.storage.location))
}
conv.ask(new NewSurface({
context: responses.newSurfaceContext,
notification: responses.notificationText,
capabilities: capability,
}))
}
:
.then
请注意Firebase功能当前使用Node.js 6并且当前不支持支持异步等待,因此您需要一个转发器才能在那里使用它。