1

使用带有节点异步的 $.getJSON 到运行带有 jsonp 响应的 node/express 的服务器时,我遇到了一个奇怪的错误。

我使用节点异步迭代数组对服务器进行了两次调用,但是当所有操作完成后,第二个结果具有一些包含第一个值的属性。

奇怪的是服务器端响应正在返回 - 因为返回的属性之一是正确的 - 但另一个属性看起来在第二次调用时被第一次调用的属性覆盖。

在服务器端,我已经对其进行了调试并检查了返回正确结果的 res.jsonp 行,我还使用一些控制台日志记录服务器端对其进行了检查。

下面的代码 - TLDR 结果如下:

    //Expecting results to be:
    [
      {"series":1, options:{serverSays:"Here is series 1"},data: [a:1,b:2,c:3]},
      {"series":2, options:{serverSays:"Here is series 2"}, data: [x:9, y:8, z:7]}
    ]

    //Actual Results are
    [
      {"series":1, options:{serverSays:"Here is series 1"}, data: [a:1,b:2,c:3]},
      {"series":2, options:{serverSays:"Here is series 2"}, data: [a:1,b:2,c:3]}
    ]

这是代码的简化版本(删除了很​​多垃圾,但逻辑保持不变):

var series = [
  {id: 1},
  {id: 2}
]

var results = [];

//A function to get data from the server and return it
function getData(id, cb)
{
  var url = serverUrl + "/GetSomeData/" + id;

  $.getJSON(url)
  .done(function (serverResponse)
  {
    console.log("Response from server: ", serverResponse)
    cb({"series": id, options: serverResponse.options, data: serverResponse.data});
  }
}

//A function to iterate through the series using async.forEach    
function iterator(s, callback)
{
  getData(s.id, function(data)
  {
    //Use the data
    results.push(data);

    //Tell async we are done with this iteration
    callback() 
  });
}

function done(err)
{
    console.log("Finished");

    //Expecting results to be
    //[
    //  {"series":1, options:{serverSays:"You Requested Series 1"},data: [a:1,b:2,c:3]}, 
    //  {"series":2, options:{serverSays:"You Requested Series 2"}, data: [x:9, y:8, z:7]}
    //]

    //Actual Results are
    //[
    //  {"series":1, options:{serverSays:"You Requested Series 1"}, data: [a:1,b:2,c:3]}, 
    //  {"series":2, options:{serverSays:"You Requested Series 2"}, data: [a:1,b:2,c:3]}
    //]
}

async.eachSeries(series, iterator, done);

我已经尝试使用异步系列、异步并行以及 promise 样式 getJSON 和回调样式 getJSON - 都显示相同的错误。

可能是我的客户端代码,或者我正在对服务器端 jsonp 做一些愚蠢的事情。

服务器端,我建立数据然后去

return res.jsonp(output);

有什么想法吗?

4

2 回答 2

0

多哈。看起来我被一个外部函数调用严重破坏了 chrome 检查器!

我终于意识到 chrome 控制台没有在检查器中显示有效数据,但是如果我 JSON.stringify 了它正确显示的对象。

例如

console.log("Server response is: ", serverResponse) //In the getJSON callback

将为不正确的对象提供树视图,如下所示:

{"series":2, options:{serverSays:"Here is series 2"}, data: [a:1,b:2,c:3]} //Incorrect data property

但是做

console.log("Server response is: ", JSON.stringify(serverResponse))

显示正确的 JSON:

{"series":2, options:{serverSays:"Here is series 2"}, data: [x:9, y:8, z:7]} //Correct data property

--

原因?我对数据做了什么。我从示例中删除的“垃圾取出”行之一是调用 highcharts 图表以设置系列数据 - 沿着

getData(s.id, function(data)
  {

    //THE OMITTED LINE
    chart.series[someSeries].setData(data.data);

    //Tell async to add data to the result list
    // and continue with the next iteration.
    callback(null, data); // err = null
});

这是绊倒了我在图表定义中遇到的一个错误,但它并没有优雅地失败,而是以某种方式破坏了 chrome 检查器......!

我猜测 node-async + $.getJSON + 多个函数 + 回调的范围地狱,这是最后一根稻草。去搞清楚!

于 2015-04-13T23:17:59.023 回答
0

我不得不承认,我找不到您的代码有任何问题。为了用尽所有选项,也许您可​​以尝试async.map

var series = [
  {id: 1},
  {id: 2}
]

//A function to get data from the server and return it
function getData(id, cb)
{
  var url = serverUrl + "/GetSomeData/" + id;

  $.getJSON(url)
  .done(function (serverResponse)
  {
    console.log("Response from server: ", serverResponse);
    cb({"series": id, options: serverResponse.options, data: serverResponse.data});
  });
}

//A function to iterate through the series using async.forEach    
function iterator(s, callback)
{
  getData(s.id, function(data)
  {
    //Tell async to add data to the result list
    // and continue with the next iteration.
    callback(null, data); // err = null
  });
}

function done(err, result)
{
    console.log("Finished");
}

// Note that map doesn't perform the iterator in order, but the result list is in order.
async.map(series, iterator, done);

您是否尝试过检查开发人员工具的网络选项卡以查看浏览器收到的服务器响应?

如果响应与预期输出相同,则此处的图片可能缺少某些内容。

于 2015-04-13T19:08:20.233 回答