Javascript Amazon Alexa Skill Lambda节点JS-Http无法工作

Javascript Amazon Alexa Skill Lambda节点JS-Http无法工作,javascript,get,alexa,alexa-skills-kit,alexa-sdk-nodejs,Javascript,Get,Alexa,Alexa Skills Kit,Alexa Sdk Nodejs,我想知道有没有人能帮我,因为我正用这个把头撞在墙上。几天来我一直在寻找答案,尝试了各种方法,下面是我得到的最接近的答案 基本上,我正在家里建立一个Alexa技能供个人使用,用来给我的儿子奖励分数,并且它会在我们的厨房仪表板上更新。我可以很好地发布分数,更新仪表板(更新firebase db),但当我问alexa他有多少分数时,我无法得到分数。我的代码如下 const GetPointsHandler = { canHandle(handlerInput) { const reques

我想知道有没有人能帮我,因为我正用这个把头撞在墙上。几天来我一直在寻找答案,尝试了各种方法,下面是我得到的最接近的答案

基本上,我正在家里建立一个Alexa技能供个人使用,用来给我的儿子奖励分数,并且它会在我们的厨房仪表板上更新。我可以很好地发布分数,更新仪表板(更新firebase db),但当我问alexa他有多少分数时,我无法得到分数。我的代码如下

const GetPointsHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'HowManyPointsDoesNameHaveIntent';
  },
  handle(handlerInput) {

      var options = {
        "method": "GET",
        "hostname": "blah-blah-blah.firebaseio.com",
        "port": null,
        "path": "/users/Connor/points.json",
        "headers": {
          "cache-control": "no-cache"
        }
      };

      var req = https.request(options, function (res) {
        var chunks = [];

        res.on("data", function (chunk) {
          chunks.push(chunk);
        });

        res.on("end", function () {
          var body = Buffer.concat(chunks);
          //console.log(body.toString());
          total = body.toString();

        });
    });

    req.end();

    speechOutput = "Connor has " + total + " points";

    return handlerInput.responseBuilder
      .speak(speechOutput)
      .getResponse();
  },
};
当我问alexa的时候,结果是“Connor有未定义的分数”,但是如果我马上再问,它就可以了

当我在浏览器中加载json端点时,它实际上只是显示值,所以我认为不需要深入研究响应

我知道请求模块应该更容易,但是如果我使用VS代码命令行安装该模块并上载该函数,因为文件变得如此之大,并且具有所有模块依赖项,我无法再在线编辑该函数,因为它超出了大小限制,所以如果可能的话,我希望避免这种情况


我知道,该功能将更好地作为一个助手,我会这样做,一旦我得到这个工作。我不需要特别漂亮,只需要它工作。

Node.js默认情况下是异步的,这意味着在GET请求完成之前调用响应生成器

解决方案:使用异步等待,类似于

异步句柄(handlerInput){ 变量选项={ “方法”:“获取”, “主机名”:“blah blah blah.firebaseio.com”, “端口”:空, “路径”:“/users/Connor/points.json”, “标题”:{ “缓存控制”:“无缓存” } }; var req=等待https.request(选项、功能(res)){ var chunks=[]; res.on(“数据”,函数(块){ 推(chunk); }); res.on(“结束”,函数(){ var body=Buffer.concat(块); //console.log(body.toString()); total=body.toString(); }); }); 请求结束(); speechOutput=“康纳有”+总分+”分; 返回handlerInput.responseBuilder .讲话(语音输出) .getResponse();
},这是因为NodeJ的异步行为。节点不会等待您的
http
请求完成。因此,
speechOutput=“Connor有”+total+“点数”total
的值之前执行code>。因此,
未定义

要做到这一点,你必须使用
承诺
。编写一个单独的函数来触发
http
请求。检查一下,看看是怎么做的。您可以将其用作任何请求的通用方法

例:


我试过上面的代码,它工作得很好。这对我来说是全新的,因为我刚刚开始使用NodeJS。我也会按照建议研究蓝图。非常感谢你的帮助,这已经困扰了我大约一个星期了!请注意,请阅读async!抱歉,经过深思熟虑,这实际上不起作用。我原以为是的,但它实际上做了和以前一样的事情,先返回undefined。我很困惑,因为它总是在第二次工作,大概是因为变量在Alexa读取后被设置。非常感谢您的帮助,我刚刚开始了解异步性,所以这是一个非常有用的帮助。我将尝试上面提到的方法,将示例分离出来供我使用并发回。非常感谢您的帮助。仍然不确定这里发生了什么,但是即使有了上面的代码更改,我仍然没有定义。我已经按照上面的建议将请求放入它自己的函数中,并按照上面的方法调用它,但仍然没有骰子。只有在第二次请求时,我才得到一个值。编辑:我犯了一个错误,上面的工作非常完美,非常感谢大家的帮助,这正是我所需要的,现在我对异步的了解比我今天早上醒来时多得多。再次感谢。
function httpGet(options) {
  return new Promise(((resolve, reject) => {
    const request = https.request(options, (response) => {
      response.setEncoding('utf8');
      let returnData = '';    
      if (response.statusCode < 200 || response.statusCode >= 300) {
        return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
      }    
      response.on('data', (chunk) => {
        returnData += chunk;
      });    
      response.on('end', () => {
        resolve(JSON.parse(returnData));
      });    
      response.on('error', (error) => {
        reject(error);
      });
    });
    request.end();
  }));
}
async handle(handlerInput) {
   var options = {
        "method": "GET",
        "hostname": "blah-blah-blah.firebaseio.com",
        "port": null,
        "path": "/users/Connor/points.json",
        "headers": {
          "cache-control": "no-cache"
        }
      };
   const response = await httpGet(options);
   var total = 0;
   if (response.length > 0) {
      // do your stuff
      //total = response
   }
   speechOutput = "Connor has " + total + " points";
   return handlerInput.responseBuilder
     .speak(speechOutput)
     .getResponse();
}