异步获取数据,将结果聚合到对象。对象是否默认由javascript锁定?

时间:2016-08-24 09:42:11

标签: javascript json asynchronous

假设我想从1000台服务器获取一些数据。每个服务器返回相同的json结构。虚拟示例:

{
    logins: 5000,
    clicks: 1000
}

假设我需要汇总每个服务器响应的所有登录信息。

我不想查询所有json然后执行求和,而是想在每个回调中执行它(= 1000次)。基本示例:

var result = 0;

$http.get(url).then(function(response) {
    result += response.data.logins;
});

解释为什么需要锁定的示例:

如果我的第一台服务器返回1000,则第二台2000和第三台3000;

假设第二次回调被称为我的承诺,无论出于何种原因,第二次还没有结束。

如果结果没有锁定,那么在第三次回调结束时它可能会等于4000,这是错误的(正确的值是6000);

那么你觉得男人们怎么样?结果是否自动锁定?如果没有,在js中创建锁定模式是否容易?

感谢您的回答!

1 个答案:

答案 0 :(得分:1)

我更新了答案,因为问题已被编辑:

如果您发送了许多ajax调用请求,响应可能不会按顺序排列,因此如果您需要订单,则可以强制ajax调用同步运行(if you use $http from Angular you can't)。

但我永远不会这样做(我会一直使用异步),特别是因为您要发送的请求数量...

如果你想要,你可以做一些事情,比如在上一次成功回调中调用下一个端点:

$http.get(url).then(function(response) {
    result += response.data.logins;
    $http.get(url).then(function(response) {
        result += response.data.logins;
        /// ... (use a loop)
    });
});

示例:



const data = [
{
  isActive: "1",
  logins: 1000,
  clicks: 1000
},
{
  isActive: "1",
  logins: 2000,
  clicks: 1000
},
{
  isActive: "1",
  logins: 3000,
  clicks: 1000
}];

const callApi = (index, timeout) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve({data: data[index]}), timeout);
  })
};

let result = 0;
let timeouts = [0, 3000, 0];

const callback = (resp, index) => {
  result += resp.data.logins;
  console.log(`Result now in callback ${index + 1}:`, result);
	
  if (index < timeouts.length - 1) {
    index++;
    callApi(index, timeouts[index]).then(resp => callback(resp, index))
  }
		
}

callApi(0, timeouts[0]).then(resp => callback(resp, 0))
&#13;
&#13;
&#13;

根据您想要实现的目标,我会使用密钥在回调中跟踪请求,即使您需要它也可以使用服务器。

如果您只需要所有&#39;登录的总和&#39;计数器,你不需要订单

&#13;
&#13;
const data = [
{
  isActive: "1",
  logins: 1000,
  clicks: 1000
},
{
  isActive: "1",
  logins: 2000,
  clicks: 1000
},
{
  isActive: "1",
  logins: 3000,
  clicks: 1000
}];

const callApi = (index, timeout) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve({data: data[index]}), timeout);
  }) 
};

let result = 0;
[0, 3000, 0].forEach((timeout, index) => {
  callApi(index, timeout)
    .then(res => {
      result += res.data.logins
      console.log(`Result now in callback ${index + 1}:`, result)
    })
});
&#13;
&#13;
&#13;