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对象_Javascript_Loops_Asynchronous_Promise_Synchronization - Fatal编程技术网

同步迭代javascript对象

同步迭代javascript对象,javascript,loops,asynchronous,promise,synchronization,Javascript,Loops,Asynchronous,Promise,Synchronization,我有一个这样的目标: let myObject = { 'db1': [db1_file1Id,db1_file2Id,db_1file3Id], 'db2': [db2_file1Id, db2_file2Id] ... } 我遍历这个对象,每次迭代:我连接到数据库,检索文件,做一些事情,然后保存文件。基本上是异步的 for (let prop in myObject) { if (myObject.hasOwnProperty(prop)) { doStuff(pr

我有一个这样的目标:

let myObject = {
'db1': [db1_file1Id,db1_file2Id,db_1file3Id],
'db2': [db2_file1Id, db2_file2Id]
...
}
我遍历这个对象,每次迭代:我连接到数据库,检索文件,做一些事情,然后保存文件。基本上是异步的

  for (let prop in myObject) {
    if (myObject.hasOwnProperty(prop)) {
      doStuff(prop, myObject[prop]);
    }
  }
现在,doStuff函数确保我有一个局部作用域,因此没有不一致。但是,由于每个循环中的异步操作,执行仍然是不同步的。我基本上需要一个数据库在进入下一个数据库之前被完全处理。我该如何解决这个问题

我想到的一种方法是使用递归循环。但根据我的理解,这需要我广泛地改变我的数据结构,这在imo中是次优的

let arr; //containing my data

process(x) {
 if (x < arr.length){
   //process(x+1) is called inside doStuff after asynchronous operations are complete
   doStuff(arr[x]);
 }
}
let-arr//包含我的数据
过程(x){
如果(x
Promise对象表示异步操作的最终完成(或失败)及其结果值。你可以试试看

$(“#myPara”).delay(4500).fadeOut().promise().done(函数()){
$(“#我的标题”).attr(“样式”,“显示:无;”);

对于(var i=10;i,Promise对象表示异步操作的最终完成(或失败)及其结果值

$(“#myPara”).delay(4500).fadeOut().promise().done(函数()){
$(“#我的标题”).attr(“样式”,“显示:无;”);

对于(var i=10;i,您可以使用您在最后提出的解决方案,使用
Object.entries(obj)
。例如

let arrProps = Object.entries(myObject);

process(index) {
 if (index < arrProps.length){
   // Call the callback once you complete execution of doStuff
   doStuff(arrProps[index], () => process(index + 1));
 }
}

或者,如果您想在
循环中为…使用
,您可以使用生成器函数。

您可以使用最后提出的解决方案,使用
Object.entries(obj)
。例如

let arrProps = Object.entries(myObject);

process(index) {
 if (index < arrProps.length){
   // Call the callback once you complete execution of doStuff
   doStuff(arrProps[index], () => process(index + 1));
 }
}

或者,如果您想在
循环中为…使用
,也可以使用生成器函数。

一种解决方案是使
doStuff
返回一个,您可以使用该函数通过调用
然后
来构建承诺链

Bluebird promise库通过和提供此功能

您可以将其实现为:

Promise.forEachSeries = function(array, action) {
  return array.reduce(function(prevPromise, value, index, array) {
    return prevPromise.then(function() {
      return action(value, index, array);
    });
  }, Promise.resolve());
}
您可以这样使用它:

Promise.forEachSeries(arr, doStuff);

一种解决方案是让
doStuff
返回一个可用于通过调用
then
构建承诺链的值

Bluebird promise库通过和提供此功能

您可以将其实现为:

Promise.forEachSeries = function(array, action) {
  return array.reduce(function(prevPromise, value, index, array) {
    return prevPromise.then(function() {
      return action(value, index, array);
    });
  }, Promise.resolve());
}
您可以这样使用它:

Promise.forEachSeries(arr, doStuff);

下面将执行您要求的操作,它返回一个解析值数组

如果其中任何一个拒绝,是否要停止处理?如果需要进行某些更改,现在如果其中任何一个拒绝,它将拒绝,并且不会继续处理对象中的键(对象名为
myObject
):

var myObject={
“一”:[“一”],
“两个”:[“两个”]
};
var doStuff=arr=>
console.log(“开始:”,arr[0])||
承诺。解决(arr[0]);
var[承诺、结果]=
Object.keys(myObject)
.减少(
([承诺,结果],关键)=>
[
许诺
.那么(
解析=>
doStuff(myObject[键])
)
.那么(
resolve=>results.push(解析)&&resolve
)
.那么(
resolve=>console.log(“完成:”,resolve)
)
后果
]
,[Promise.resolve(),[]
)
我保证,那么(
_ => {
日志(“全部完成”,结果)
}

)
以下命令将执行您要求的操作,它返回一个解析值数组

如果其中任何一个拒绝,是否要停止处理?如果需要进行某些更改,现在如果其中任何一个拒绝,它将拒绝,并且不会继续处理对象中的键(对象名为
myObject
):

var myObject={
“一”:[“一”],
“两个”:[“两个”]
};
var doStuff=arr=>
console.log(“开始:”,arr[0])||
承诺。解决(arr[0]);
var[承诺、结果]=
Object.keys(myObject)
.减少(
([承诺,结果],关键)=>
[
许诺
.那么(
解析=>
doStuff(myObject[键])
)
.那么(
resolve=>results.push(解析)&&resolve
)
.那么(
resolve=>console.log(“完成:”,resolve)
)
后果
]
,[Promise.resolve(),[]
)
我保证,那么(
_ => {
日志(“全部完成”,结果)
}

);
以下代码可能与您的要求很接近。我使用索引
I
j
分别循环浏览数据库和文件:

var dbs={
db1:[“q”、“w”、“e”、“r”],
db2:[“t”,“y”]
};
变量名称=Object.keys(dbs);
var db,x,i=0,j=0;
如果(names.length>0){
db=dbs[name[i]];
x=db[j];
控制台日志(“启动”);
异步处理(x)
.然后(成功)
.捕获(失败时);
}
功能失效(e){
console.log(“[FAILURE]”,e);
控制台日志(“结束”);
}
函数onSuccess(xx){
console.log(“[SUCCESS]”,xx);
j=(j+1)%db.length;//下一个j
如果(j==0)i=i+1;//下一个i
如果(i1){
解析(x+x);
}否则{
拒绝(“运气不好,再试一次”);
}
}, 1000);
});

}
以下代码可能与您的要求非常接近。我使用索引
I
j
分别循环浏览数据库和文件:

var dbs={
db1:[“q”、“w”、“e”、“r”],
db2:[“t”,“y”]
};
变量名称=Object.keys(dbs);
var db,x,i=0,j=0;
如果(names.length>0){
db=dbs[name[i]];
x=db[j];
console.log(“开始”)