空字符串响应由于同步不良

时间:2018-08-03 12:18:53

标签: javascript node.js callback promise dialogflow

我启动了一个简单的代理,并向其中添加了一个名为“ myIntent ”的基本Intent。我通过Firebase内联编辑器启用了实现功能,并按照说明,在提供的基础代码中添加了一个名为“ myFunction ”的函数。此函数包含对https://reqres.in/api/users/2的HTTPS GET请求示例。
我的目标是根据对外部API的GET调用提供的响应,对意图添加响应。

脚本

'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const https=require('https');

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

function myFunction(agent){

    var info='';
    var options = {
         host: `reqres.in`,
         path: `/api/users/2`,
         method: 'GET',
         headers: {'Accept':'application/json'}
    };

    var req = https.request(options, (res) => {
         console.log('statusCode:', res.statusCode);
         console.log('headers:', res.headers);

         let data='';

         res.on('data', (d) => {
           data+= d;
         });

         res.on('end', () => {
           console.log(data);
           let jsonObject= JSON.parse(data);
           info=jsonObject.id;

           console.log(JSON.stringify(info));
         });
    });

    req.on('error', (e) => {
       console.log('ERROR');
       console.error(e);
    });

    agent.add(JSON.stringify(info));
    req.write('End of request');
    req.end();  


}



    let intentMap = new Map();
    intentMap.set('myIntent',myFunction);
    agent.handleRequest(intentMap);
    });

意图已正确触发,但我的问题是代理响应始终为空字符串。
enter image description here

我对http调用,函数回调没有太多经验,但我认为问题出在那行

 agent.add(info);

我的脚本末尾是在http调用末尾之前执行的。
我进行了各种尝试,尝试在https://www.promisejs.org/之后的myFunction内插入一个promise,但是它们都只包含错误消息。
各种各样的帮助将不胜感激,我理解这个问题,但是我无法以任何方式解决。

P.S:agent.handleRequest docs reference

我尝试使用Promise失败

'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const https=require('https');

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));


 function myFunction(agent){
    var info='';
    var p=new Promise((resolve,reject)=>{

        var options = {
        host: `reqres.in`,
        path: `/api/users/2`,
        method: 'GET',
        headers: {'Accept':'application/json'}
        };

        var req = https.request(options, (res) => {
            console.log('statusCode:', res.statusCode);
            console.log('headers:', res.headers);
            let data='';

        res.on('data', (d) => {
            data+= d;
        });

        res.on('end', () => {
            console.log(data);
            let jsonObject= JSON.parse(data);
            info=jsonObject.id;

             console.log(JSON.stringify(info));
            });
        });

        req.on('error', (e) => {
            console.log('ERROR');
            console.error(e);
        });

        req.write('End of request');
        req.end();
        resolve(info);
    });

    p.then((agent)=>{
        agent.add(info);
    });

    }
let intentMap = new Map();
  intentMap.set('myIntent',myFunction);
  agent.handleRequest(intentMap);
});

1 个答案:

答案 0 :(得分:0)

您仍在{em>立即使用info做事-现在可以解决诺言-而不是通过异步回调来完成。将agent.add()调用或resolve()调用放在end处理程序中,以便仅在数据完成后才发生:

var p = new Promise((resolve,reject) => {
    var options = {
        host: `reqres.in`,
        path: `/api/users/2`,
        method: 'GET',
        headers: {'Accept':'application/json'}
    };

    var req = https.request(options, (res) => {
        console.log('statusCode:', res.statusCode);
        console.log('headers:', res.headers);
        let data='';

        res.on('data', (d) => {
            data+= d;
        });

        res.on('end', () => {
            console.log(data);
            let jsonObject = JSON.parse(data);
            resolve(jsonObject.id);
//          ^^^^^^^^^^^^^^^^^^^^^^^
        });
    });

    req.on('error', (e) => {
        reject(e); // don't forget this
    });

    req.write('End of request');
    req.end();
});

p.then(info => {
//     ^^^^ the fulfillment value that you passed to resolve()
    agent.add(info);
}, err => {
    console.log('ERROR');
    console.error(err);
});