确保在另一个呼叫之前执行了与异步呼叫的foreach?
我具有多个功能,具有多个foreach
loops:
async insertKpbDocument(jsonFile) {
jsonFile.doc.annotations.forEach((annotation) => {
annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
return jsonFile;
}
我需要确保foreach
loop中的异步代码调用this.addvertex
函数是在执行下一个之前,确实要完成。
但是,当我记录变量时,似乎this.Addrelation
函数在第一个循环真正结束之前被调用。
因此,我尝试在每个循环之前添加等待
术语:
await jsonFile.doc.annotations.forEach(async (annotation) => {
await annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
await annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
但是相同的行为。
也许是日志函数具有延迟?有什么想法吗?
I have a function with multiple forEach
loops:
async insertKpbDocument(jsonFile) {
jsonFile.doc.annotations.forEach((annotation) => {
annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
return jsonFile;
}
I need to make sure that the async code in the forEach
loop calling the this.addVertex
function is really done before executing the next one.
But when I log variables, It seems that the this.addRelation
function is called before the first loop is really over.
So I tried adding await
terms before every loops like so :
await jsonFile.doc.annotations.forEach(async (annotation) => {
await annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
await annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
But same behavior.
Maybe it is the log function that have a latency? Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如我们已经讨论的那样,
等待
不会暂停.foreach()
循环,并且不会使迭代的第二项等待处理第一个项目。因此,如果您真的想对项目进行异步测序,则无法真正使用.foreach()
循环来完成它。对于这种类型的问题,
异步/等待
与循环的普通非常有效,因为它们确实暂停了执行实际
语句的实际对为您提供异步操作的测序,这是您想要的。另外,它甚至可以与
循环的嵌套一起使用,因为它们都处于相同的函数范围:
向您展示它可以使用 and and
来使用
多少等待
,可以这样做:您可以编写类似同步的代码,实际上是在测序异步操作。
如果您确实避免了循环的任何
,而您的实际要求只是所有调用
addvertex()
在任何调用addRelation(),然后您可以在使用
.map()
而不是.foreach()
的情况下执行此操作,然后收集一系列承诺,然后使用Promise。 all()
等待一系列承诺:为了完全了解它的工作原理,它运行所有
addvertex()
并行呼叫一次注释,请等待所有等待所有然后运行所有addRelation()
并联呼叫以进行一个注释,然后等待所有人完成。它并行运行所有注释本身。因此,除了注释中,这不是很实际的测序,但是您接受了一个具有相同测序的答案,并说它有效,因此我显示了更简单的版本以进行完整。如果您确实需要对每个单独的
addvertex()
调用,这样您才能在上一个之前拨打下一个,并且您仍然不会使用 for 循环,然后您可以使用.Reduce()
放置在辅助功能中的Promise模式来手动对数组的同步访问序列:这将完全对所有内容进行序列。 It will do this type of order:
where it waits for each operation to finish before going onto the next one.
As we've discussed,
await
does not pause a.forEach()
loop and does not make the 2nd item of the iteration wait for the first item to be processed. So, if you're really trying to do asynchronous sequencing of items, you can't really accomplish it with a.forEach()
loop.For this type of problem,
async/await
works really well with a plainfor
loop because they do pause the execution of the actualfor
statement to give you sequencing of asynchronous operations which it appears is what you want. Plus, it even works with nestedfor
loops because they are all in the same function scope:To show you how much simpler this can be using
for/of
andawait
, it could be done like this:You get to write synchronous-like code that is actually sequencing asynchronous operations.
If you are really avoiding any
for
loop, and your real requirement is only that all calls toaddVertex()
come before any calls toaddRelation()
, then you can do this where you use.map()
instead of.forEach()
and you collect an array of promises that you then usePromise.all()
to wait on the whole array of promises:To fully understand how this works, this runs all
addVertex()
calls in parallel for one annotation, waits for them all to finish, then runs all theaddRelation()
calls in parallel for one annotation, then waits for them all to finish. It runs all the annotations themselves in parallel. So, this isn't very much actual sequencing except within an annotation, but you accepted an answer that has this same sequencing and said it works so I show a little simpler version of this for completeness.If you really need to sequence each individual
addVertex()
call so you don't call the next one until the previous one is done and you're still not going to use afor
loop, then you can use the.reduce()
promise pattern put into a helper function to manually sequence asynchronous access to an array:This will completely sequence everything. It will do this type of order:
where it waits for each operation to finish before going onto the next one.
foreach
将返回void
,因此等待它不会做太多。您可以使用MAP
返回您现在在foreach
中创建的所有承诺,并使用Promise.all
等待全部:foreach
will returnvoid
so awaiting it will not do much. You can usemap
to return all the promises you create now in theforEach
, and usePromise.all
to await all:我了解您可以同时运行所有AddVertex。将简化与将MAP拆分成两套不同的承诺相结合。我的想法:
您有更多的循环,但是它可以做到您所需要的
I understand you can run all the addVertex concurrently. Combining reduce with map splitted into two different set of promises you can do it. My idea:
You have more loops, but it does what you need I think
foreach
对数组中的每个元素执行回调,并且不等待任何内容。使用等待
基本上是写promise.then()
的糖,并嵌套在然后()然后()
呼叫中的所有内容。但是foreach
不返回承诺,因此等待arr.foreach()
是毫无意义的。它不是编译错误的唯一原因是因为异步/等待规格说您可以等待
任何东西,如果不是保证,您只需获得其值...foreach foreach
只给您void
。如果您希望某些事情按顺序发生,则可以在循环中等待等待:
edit:在键入此几个其他答案和评论时。 ..您不想为循环使用
,您可以使用
Promise.All
,但可能仍然有些混乱,因此,我将在上面的说明以防万一它有帮助。forEach
executes the callback against each element in the array and does not wait for anything. Usingawait
is basically sugar for writingpromise.then()
and nesting everything that follows in thethen()
callback. ButforEach
doesn't return a promise, soawait arr.forEach()
is meaningless. The only reason it isn't a compile error is because the async/await spec says you canawait
anything, and if it isn't a promise you just get its value...forEach
just gives youvoid
.If you want something to happen in sequence you can
await
in afor
loop:Edit: While typing this a couple other answers and comments happened... you don't want to use a
for
loop, you can usePromise.all
but there's still maybe some confusion, so I'll leave the above explanation in case it helps.异步/等待
不在foreach
中。一个简单的解决方案:
.foreach()
将替换为(.. of ..)而替换。此类似的问题。
如果启用了
no-code
弹性规则,则您将获得(..)使用的刺警告/错误。有很多讨论/观点 this主题。
恕我直言,这是一种场景,我们可以在其中抑制警告 eslint-disable-disable-next-next-line 或方法/类。
示例:
代码非常可读,并且可以按预期工作。要使用
.foreach()
获得类似的功能,我们需要一些我认为浪费精力的承诺/观察到的杂技。async/await
does not withinforEach
.A simple solution: Replace
.forEach()
withfor(.. of ..)
instead.Details in this similar question.
If
no-iterator
linting rule is enabled, you will get a linting warning/error for usingfor(.. of ..)
. There are lots of discussion/opinions on this topic.IMHO, this is a scenario where we can suppress the warning with eslint-disable-next-line or for the method/class.
Example:
The code is very readable and works as expected. To get similar functionality with
.forEach()
, we need some promises/observables acrobatics that i think is a waste of effort.