简体   繁体   English

异步获取数据,将结果聚合到一个对象中。 默认情况下,对象是否被javascript锁定?

[英]Async fetch data, aggregate the result to an object. Is the object locked by javascript by default?

Let's say I wanna get some data from 1000 servers. 假设我要从1000台服务器中获取一些数据。 Each server returns the same json structure. 每个服务器返回相同的json结构。 Dummy Example: 虚拟示例:

{
    logins: 5000,
    clicks: 1000
}

Let's say that I need to sum all logins from each server response. 假设我需要汇总每个服务器响应中的所有登录信息。

Instead of query all the json and then perform the sum, I would like to do it in every callbacks (= 1000 times). 我想在每个回调(= 1000次)中执行此操作,而不是查询所有json然后执行总和。 Basic Example: 基本示例:

var result = 0;

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

An example to explain why the lock is necessary: 解释为什么需要锁定的示例:

If my first server returns 1000, the second 2000 and the third 3000; 如果我的第一台服务器返回1000,则第二台服务器返回2000,第三台服务器返回3000;

Let's say the second hasn't finished yet when the third callback is called my the promise, for whatever reason. 假设由于某种原因,当第三个回调称为我的诺言时,第二个还未完成。

If there is no lock on result, it will probably equal 4000 at the end of the third callback, which is wrong (the correct value is 6000); 如果没有锁定结果,则在第三个回调结束时可能等于4000,这是错误的(正确值为6000);

So what do you think guys ? 那你们觉得呢? Is the result locked automatically or not ? 结果是否自动锁定? If not, is it easy to create the lock pattern in js ? 如果不是,是否很容易在js中创建锁定模式?

Thanks for your answers ! 感谢您的回答!

I update the answer because the question was edited: 我更新了答案,因为问题已编辑:

If you send many ajax calls requests, responses might not come in order, so if you need the order, you can force the ajax calls to run synchronously ( if you use $http from Angular you can't ). 如果发送许多ajax调用请求,则响应可能无法按顺序进行,因此,如果需要该命令,则可以强制ajax调用同步运行( 如果使用Angular中的$ http则不能 )。

But I would never do that (I would always use async), especially because the number of request you want to send... 但是我永远不会那样做(我总是会使用异步),尤其是因为您要发送的请求数量...

If you want you can do something like just call the next endpoint on the previous success callback: 如果您愿意,可以执行类似的操作,只需在上一个成功回调中调用下一个端点:

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

Example: 例:

 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)) 

Depending on what you want to achieve I would use a key to track the request in the callback even using the server if you need it. 根据您要实现的目标,我将使用键在回调中跟踪请求,即使您需要也可以使用服务器。

If you only need the sum of all 'logins' counters and you do not need the order 如果您只需要所有“登录”计数器的总和,而无需订购

 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) }) }); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM