Alexa отвечает перед возвратом данных - PullRequest
2 голосов
/ 28 мая 2019

Я новичок в обещаниях, async / await и Alexa / lambda, так что терпите меня.

Моя функция возвращается до возврата данных. У меня была похожая проблема, когда я получал ошибку, но с тех пор я немного отредактировал свою функцию и поэтому задавал новый вопрос. Теперь я больше не получаю сообщение об ошибке, но вместо этого сначала возвращаются мои данные, затем выполняется обещание.

Я попытался переписать обещание / функцию после прочтения множества форумов разработчиков SO, google и amazon. Кажется, у меня ничего не работает.

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 голосов
/ 30 мая 2019

Почти_Ашли, основываясь на вашем собственном ответе, некоторые идеи, которые у меня есть:

  1. сделали предположение, что httpsGetIntent() возвращает Promsie, который доставляет resultData.
  2. обещанныйcheckAuthenticationStatus(), написав адаптер checkAuthenticationStatusAsync().
  3. объединил команды .speak() в заключительные предложения .then() и .catch().
  4. позволял настраивать конкретные ошибки путем украшения с помощью.title свойство, которое используется в финале .catch() в качестве заголовка карты.Любые неокрашенные ошибки будут по умолчанию «Извините» (или что вы хотите).
// 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 способ, не обязательно Кстати, написать код.Пожалуйста, не стесняйтесь набег на идеи.

0 голосов
/ 30 мая 2019

Ваш лучший друг - асинхронный / ожидающий.Пожалуйста, используйте что-то вроде this или как this для доступа к API.

0 голосов
/ 29 мая 2019

Несмотря на то, что он не до конца проработан (мне нужно рассмотреть часть обработки ошибок), я хотел бы поделиться своим решением здесь на тот случай, если кто-нибудь наткнулся на этот пост и ему нужна помощь.

Я переместил обещание за пределы функции checkAuthentication и вернул данные, когда они были обработаны. Затем я связал обещание с .then () и передал ему возвращенные данные, и предложил Алексею заговорить.

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();
        });
    },
};
...