Alexa在返回数据之前做出响应

时间:2019-05-28 20:13:55

标签: node.js lambda promise alexa alexa-skills-kit

我对诺言,异步/等待和Alexa / lambda还是陌生的,所以请耐心等待。

我的函数在返回数据之前先返回。我遇到了类似的问题,但我遇到了一个错误,但是此后我对函数进行了很多编辑,因此提出了一个新问题。我现在不再遇到错误,而是先返回我的数据,然后执行诺言。

在阅读了很多SO,google和Amazon开发人员论坛后,我尝试重新编写Promise /功能。似乎对我没有任何帮助。

const IntentRequest = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
    },
    async handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
        let responseData, promise;

         checkAuthenticationStatus(handlerInput,function(json){
            console.log('waited!')
            if(json.error) {
                return handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse();
            } else if(json.noerror && json.noerror.okay == 'true'){
                console.log('starting to get intent data')
                const url = new URL(json.noerror.okay.path);
                promise = new Promise((resolve, reject) => { 
                    console.log('start promise')
                   return httpsGetIntent(handlerInput, url).then((resultData) => {
                        console.log(resultData)
                        responseData = resultData;
                        resolve(responseData)
                        console.log('inside promise, no error, prior to return data')
                    })

            }).then((result) => { console.log('result', result)})
                return handlerInput.responseBuilder.speak('Test').getResponse();
            }

        });
        console.log('response data', responseData)

        let result = await promise;
        return result;

    },
};

在我添加的许多用于调试的console.logs()中,它们的打印如下: -“响应数据” -“等一下!” -“开始获取意图数据” -“开始承诺” -resultData -“承诺内,没有错误,先返回数据”

3 个答案:

答案 0 :(得分:0)

虽然还没有完全充实(我需要解决错误处理部分),但我想在这里分享我的解决方案,以防有人偶然发现这篇文章并需要帮助。

我将诺言移至checkAuthentication函数之外,并在处理后返回了数据。然后,我将诺言与.then()链接起来,并将返回的数据传递给它,并提示Alexa讲话。

const IntentRequest = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
    },
    async handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
        let responseData, promise;
        return new Promise((resolve, reject) => {
            checkAuthenticationStatus(handlerInput, async function(json) {
                if (json.error) {
                    return handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse();
                } else if (json.noerror && json.noerror.okay == 'true') {
                    const url = new URL(json.noerror.okay.path);
                    let resultD = await httpsGetIntent(handlerInput, url, function(resultData) {
                        if (resultData) {
                            return resolve(resultData);
                        } else {
                            return resolve(handlerInput.responseBuilder.speak('False Test').getResponse());
                        }
                    })

                }
            })

        }).then((data) => {
            return handlerInput.responseBuilder.speak(data.response.outputSpeech.text).getResponse();
        });
    },
};

答案 1 :(得分:0)

Almost_Ashleigh,根据您自己的回答,我有一些想法:

  1. 假设httpsGetIntent()返回了一个提供resultData的Promsie。
  2. 通过编写适配器checkAuthenticationStatus()来实现checkAuthenticationStatusAsync()
  3. .speak()命令合并到最后的.then().catch()子句中。
  4. 允许使用.title属性修饰来定制特定错误,该属性在最后的.catch()中用作cardTitle。任何未修饰的错误将默认为“对不起”(或您想要的任何内容)。
// in a suitable scope ...
function checkAuthenticationStatusAsync(handlerInput) {
    return new Promise((resolve, reject) {
        checkAuthenticationStatus(handlerInput, (json) => {
            if (json.error || !json.noerror || json.noerror.okay !== 'true') {
                let err = new Error(messages.NO_ACCESS); // or maybe a separate error message per error case?
                err.title = 'Unauthorized Request';
                reject(err);
            } else {
                resolve(json);
            }
        });
    });
}

// ... and ...
const IntentRequest = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
    },
    handle(handlerInput) {
        return checkAuthenticationStatusAsync(handlerInput)
        .then((json) => httpsGetIntent(handlerInput, new URL(json.noerror.okay.path)))
        .then((resultData) => {
            if (resultData) {
                // success path ends here
                return handlerInput.responseBuilder.speak(resultData.response.outputSpeech.text).getResponse();
            } else {
                throw new Error('No result data returned'); // throws to the .catch() below
            }
        })
        .catch(err => {
            // all errors end up here.
            return handlerInput.responseBuilder.speak(err.message).withSimpleCard(err.title || 'Sorry', err.message).getResponse();
            throw err; // to keep handle's caller informed
        });
    },
};

注意,这是编写代码的 a 方法,不一定是 the 方法。请随时突袭想法。

答案 2 :(得分:0)

您最好的朋友是异步/等待。请使用类似this或类似this的名称来访问API。