Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步并在多个对象数组中等待,即1000多个对象_Javascript_Node.js_Cassandra - Fatal编程技术网

Javascript 异步并在多个对象数组中等待,即1000多个对象

Javascript 异步并在多个对象数组中等待,即1000多个对象,javascript,node.js,cassandra,Javascript,Node.js,Cassandra,我有1000多个具有这些属性的对象数组,如: 常量empArr=[{ empName:'sds', empId:'e3', dob:'22-12-2', …等等 }]; 我试过使用promise.allpromises来说明问题,但我想更有效地解决问题。因此,我需要一些帮助 function makeDBInsert(empArr) { const dbArr = []; const promises = []; const LEN = empArr.length; /** this func

我有1000多个具有这些属性的对象数组,如:

常量empArr=[{ empName:'sds', empId:'e3', dob:'22-12-2', …等等 }];

我试过使用promise.allpromises来说明问题,但我想更有效地解决问题。因此,我需要一些帮助

function makeDBInsert(empArr) {
const dbArr = [];
const promises = [];
const LEN = empArr.length;

/** this function returns promise containing emp age **/
function getEmpAge(empId) {
return db.execute('select age from emp where "empId" = ?', [empId]);
} 

for (let i = 0; i < LEN; i += 1) {
const obj = {
name: empArr[i].empName, 
empId: empArr[i].empId
}
promises.push(getEmpAge(obj.empId);
dbArr.push(obj);
}

return Promise.all(promises).then((empDetail) => {
const dbObj = empDetail.map((emp, i) => {
return {
dbArr[i].age: emp.age
}
});
return db.insert('insert into emp ("name", "id", "age") values ('?', '?', '?');', Object.values(obj));
}).catch(err => console.error(err));
} 
因此,这里empArr在数组中有1000多个对象。在这里,我从db获取emp age,它返回包含emp id的承诺。我使用promise.all来完成这项工作,而不是使用promise.all然后进行迭代,有没有更好的方法?提前谢谢


注意:请忽略代码中的语法错误。我在这里的目的只是描述我的问题陈述。

我得到了解决方案,即一个循环可以执行所有操作,比如使用IIFE、异步等待、无承诺。所有操作以及迭代承诺响应

async function makeDBInsert(empArr) {
const modifiedArr = [];

function getEmpAge(empId) {
return db.execute('select age from emp where "empId" = ?', [empId]);
} 


await (function doDBCalls() {
empArr.forEach(async (item, i) => {
 /* getEmpAge(param) is DB call */
    const res = await getEmpAge(item.empId);
    modifiedArr.push({modified: res.age });
    // modify the object here and batch insert 
});
})();
} 

我不太了解Cassandra,但是你不能简单地从emp中查询数据库,比如select age,其中empId在1,2,3,4….1000中吗?通过这种方式,您只需进行一次查询,而不是1000次查询…关于阻止承诺。所有的事情-但为什么?塞巴斯蒂安是对的,这里的瓶颈是数千次查询,这是您应该优化的。@SebastianKaczmarek也许您也可以只进行一次查询来修改您的数据?在Cassandra中,在分区键上使用In将大部分工作负载放在协调器节点上。这对于4到5个项目来说是不错的,尽管它的表现不好,但肯定不是1000个。如果表的设计不支持在一个查询中返回1000行,那么最好的选择是进行1000个单独的查询。@Aaron谢谢,我不知道。正如我之前所说,我对卡桑德拉不太了解。不过,OP使用async/await的解决方案是个糟糕的主意,他应该避免使用itOuch!你在这里做了一件可怕的事。您正在迭代1000次,在每次迭代中,您正在创建一个承诺,并等待它实现,然后开始另一次迭代。这比Promise.all解决方案糟糕得多,因为您根本没有按照我在评论中的建议摆脱承诺,这里最大的瓶颈是什么?您正在灾难性地降低代码的执行速度。通过这种方式,您不需要使用异步代码执行-您正在强制此处的代码执行,就像它是同步的一样,这大大降低了您的应用程序的速度!是的,我强制它同步运行,因为我不想多次循环,这会占用CPU。至于DB调用[await getEmpAgeparam]Nodejs,它非常适合IO操作,Cassandra的表现也非常出色。单节点集群上的Cassandra每秒至少可以处理50k个事务。它是同步的,但不会减慢速度。我的观点是forEach中的等待会导致代码冻结,直到getEmpAge的承诺实现,然后它会解冻并继续迭代。因此,在每次迭代中,您都会强制代码等待查询完成,然后继续当前迭代中的其余代码,然后开始另一个迭代。如果您使用Promise.all,您将创建1000个承诺,您在此处创建的承诺将异步实现,并且您必须等待它们的时间将仅等于最长执行所需的时间。现在它等于它们的总和,请参见我刚刚创建的示例基准:。它显示了在这种情况下async/await如何降低代码的速度。尽管empArr上有两次迭代,但代码的执行速度仍然要快得多,因为JavaScript中的数组方法非常快。