为什么这个函数在这个expressjs路由处理程序中返回对象变得未定义?

时间:2018-04-13 10:09:12

标签: javascript node.js web-services express httprequest

我正在使用expressjs创建一个应用程序,该应用程序将实时数据从mongodb发送到javascript客户端,该客户端定期请求Web服务。 应用程序的目标是使用highcharts库显示它们。

问题在于我能够将数据传递给客户端。

我的问题是:

  1. 为什么响应对象在getLiveData()函数中是正确的,然后在被

    调用时变为未定义
    Source List contains: [123-456789, (1)23456789]
    Added 123-456789 to set.
        ... now normalized to 123456789
    Added (1)23456789 to set.
        ... now normalized to 123456789
    Set contains [(1)23456789, 123-456789].
    Unnecessary List contains [123456789, 123456789].
    Useful Set contains [123456789].
    
  2. 为什么只有在注释以下两行时才会调用requestData()函数:

    app.get("/liveDataRequest", function(req, res){ etc ...  ? 
    
  3. 这些是我的代码的关注部分:

    • 服务器端代码:server.js

      dataType: 'json',
      contentType: 'application/json',
      
    • 客户端代码:client.js

      function getLiveData(){
        var liveArray=[];
        var response;
        const changeStream = dbObject.collection('status').watch(pipeline);
      
      // start listening to changes
      changeStream.on("change", function(change) {
      console.log('in change stream');
      liveArray.push([change.fullDocument.ts , change.fullDocument.T]);
      
      response = {
          "liveArray" : liveArray
      };
      
      console.log("from getLiveData : " , reponse);
      return response;
      });      
      }
      
      app.get("/liveDataRequest", function(req, res){
      console.log('Debug 10');
      var liveResponse=getLiveData();
      console.log("liveResponse : " , liveResponse);
      res.status(200).send(liveResponse);
      console.log('Debug 20');
      });
      

    这是控制台输出,它显示在发送到客户端之前,响应对象变为未定义:

    function requestData() {
    $.ajax({
    url: 'http://localhost:3300/liveDataRequest',
    type: 'GET',
    //dataType: 'json',
    //contentType: 'application/json',
    success: function(point) {
        var series = myChart.series[0],
            shift = series.data.length > 20; // shift if the series is 
                                             // longer than 20
    
        // add the point
        myChart.series[0].addPoint(point.liveArray[0][1], true, shift);
    
        // call it again after one second
        setTimeout(requestData, 1000);    
    }
    });
    }
    

    console log capture

    PS:我对使用nodejs和javascript(以及一般的网络技术)感到陌生。

    编辑 :现在我在getLiveData()函数中使用了一个回调函数,我收到了以下错误:

    Debug 10
    liveResponse :  undefined
    Debug 20
    in change stream
    from getLiveData :  { liveArray: 
    [ [ Fri Apr 13 2018 01:39:26 GMT-0400 (EDT), 24.5 ],
     [ Fri Apr 13 2018 01:39:28 GMT-0400 (EDT), 24.8 ] ] }
    in change stream
    from getLiveData :  { liveArray: 
    [ [ Fri Apr 13 2018 01:39:25 GMT-0400 (EDT), 24.5 ],
     [ Fri Apr 13 2018 01:39:26 GMT-0400 (EDT), 24.5 ],
     [ Fri Apr 13 2018 01:39:28 GMT-0400 (EDT), 24.8 ] ] }
    Debug 10
    liveResponse :  undefined
    Debug 20
    Debug 10
    liveResponse :  undefined
    Debug 20
    

    新代码:

    Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at ServerResponse.header (/home/osboxes/Desktop/node-highcharts-10/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/home/osboxes/Desktop/node-highcharts-10/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/home/osboxes/Desktop/node-highcharts-10/node_modules/express/lib/response.js:267:15)
    at ServerResponse.send (/home/osboxes/Desktop/node-highcharts-10/node_modules/express/lib/response.js:158:21)
    at /home/osboxes/Desktop/node-highcharts-10/server2.js:242:21
    at null.<anonymous> (/home/osboxes/Desktop/node-highcharts-10/server2.js:200:9)
    at emitOne (events.js:77:13)
    at emit (events.js:169:7)
    at processNewChange (/home/osboxes/Desktop/node-highcharts-10/node_modules/mongodb/lib/change_stream.js:348:49)
    

1 个答案:

答案 0 :(得分:1)

问题一:

getLiveData()在这里没有任何回报。 您的return发生在changeStream.on(...)

您可以在这里使用callbackspromises

回调示例:

function getLiveData(handler){
    changeStream.on('change', function(change){
       //...
       handler(response);
    });
}

getLiveData(function(data){
    res.send(data);
});

承诺示例:

function getLiveData(){
    return new Promise(function (resolve, reject) {
        changeStream.on('change', function(change){
           //...
           resolve(response);
        }).on('error', reject);
    });
}

getLiveData()
    .then(function (data) {
        res.send(data)
    })
    .catch(console.error.bind(console));

问题二:

可能会调用该函数,但因为返回的响应不是有效的JSON(它将是undefined),所以成功回调没有被解雇(错误回调会)。

您可以通过查看开发工具的network标签来验证这一点。