javascript for 循环内的异步过程[重复]

2024-01-10

我正在运行以下形式的事件循环:

var i;
var j = 10;
for (i = 0; i < j; i++) {

    asynchronousProcess(callbackFunction() {
        alert(i);
    });
}

我试图显示一系列显示数字 0 到 10 的警报。问题是,当触发回调函数时,循环已经经历了几次迭代,并且显示了更高的值i。关于如何解决这个问题有什么建议吗?


The for当所有异步操作启动时,循环立即运行直至完成。当它们在未来某个时间完成并调用回调时,循环索引变量的值i所有回调都将处于其最后一个值。

这是因为for在继续循环的下一次迭代之前,循环不会等待异步操作完成,因为异步回调会在将来的某个时间被调用。因此,循环完成其迭代,然后当这些异步操作完成时调用回调。因此,循环索引已“完成”并处于所有回调的最终值。

要解决此问题,您必须为每个回调单独保存循环索引。在 Javascript 中,实现这一点的方法是在函数闭包中捕获它。这可以通过专门为此目的创建一个内联函数闭包(如下所示的第一个示例)来完成,也可以创建一个将索引传递给的外部函数,并让它为您维护唯一的索引(如下所示的第二个示例)。

截至 2016 年,如果您有完全符合规范的 ES6 Javascript 实现,您还可以使用let定义for循环变量,并且它将为每次迭代唯一定义for循环(下面的第三个实现)。但是,请注意,这是 ES6 实现中的后期实现功能,因此您必须确保您的执行环境支持该选项。

使用 .forEach() 进行迭代,因为它创建了自己的函数闭包

someArray.forEach(function(item, i) {
    asynchronousProcess(function(item) {
        console.log(i);
    });
});

使用 IIFE 创建您自己的函数闭包

var j = 10;
for (var i = 0; i < j; i++) {
    (function(cntr) {
        // here the value of i was passed into as the argument cntr
        // and will be captured in this function closure so each
        // iteration of the loop can have it's own value
        asynchronousProcess(function() {
            console.log(cntr);
        });
    })(i);
}

创建或修改外部函数并向其传递变量

如果您可以修改asynchronousProcess()函数,那么你可以将值传递到那里并获得asynchronousProcess()将 cntr 返回到回调函数,如下所示:

var j = 10;
for (var i = 0; i < j; i++) {
    asynchronousProcess(i, function(cntr) {
        console.log(cntr);
    });
}

Use ES6 let

如果你有完全支持ES6的Javascript执行环境,你可以使用let在你的for像这样循环:

const j = 10;
for (let i = 0; i < j; i++) {
    asynchronousProcess(function() {
        console.log(i);
    });
}

let声明于for像这样的循环声明将创建一个唯一的值i对于循环的每次调用(这就是您想要的)。

使用 Promise 和 async/await 进行序列化

如果您的异步函数返回一个承诺,并且您希望序列化您的异步操作以依次运行而不是并行运行,并且您正在支持的现代环境中运行async and await,那么你就有更多的选择。

async function someFunction() {
    const j = 10;
    for (let i = 0; i < j; i++) {
        // wait for the promise to resolve before advancing the for loop
        await asynchronousProcess();
        console.log(i);
    }
}

这将确保只有一次调用asynchronousProcess()一次在飞行中并且for在每个循环完成之前,循环甚至不会前进。这与之前所有并行运行异步操作的方案不同,因此它完全取决于您想要的设计。笔记:await使用 Promise,因此您的函数必须返回一个在异步操作完成时已解决/拒绝的 Promise。另请注意,为了使用await,必须声明包含函数async.

并行运行异步操作并使用Promise.all()按顺序收集结果

 function someFunction() {
     let promises = [];
     for (let i = 0; i < 10; i++) {
          promises.push(asynchonousProcessThatReturnsPromise());
     }
     return Promise.all(promises);
 }

 someFunction().then(results => {
     // array of results in order here
     console.log(results);
 }).catch(err => {
     console.log(err);
 });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javascript for 循环内的异步过程[重复] 的相关文章

  • 使用 ScriptEngine 从 JavaScript 调用 Java 方法

    我正在使用 ScriptEngine 运行 JavaScript 我希望 JavaScript 脚本能够调用 myFunction 其中 myFunction 是我的给定类中的一个方法 我知道可以将 importPackage 用于标准 J
  • 从数组数组中获取唯一值[重复]

    这个问题在这里已经有答案了 我有以下数组 let arr email protected cdn cgi l email protection email protected cdn cgi l email protection email
  • Yeoman-Angular 生成的应用程序中缺少 Angular 脚本

    我已经使用 Yeoman Angular Generator 生成了一个应用程序 但项目中缺少 angular js 和其他 Angular 文件 我可以在 Bower json 文件中看到这些依赖项 如下所示 name mi portfo
  • Jqplot 中两个系列数据的不同颜色条

    我想知道如何在 Jqplot 中为两个系列制作不同的颜色条 如果我只有一个系列数据 它的工作原理如下图所示 红色和绿色基于其值 但是 如果我有两个系列数据 我无法为每个系列数据配置两个系列颜色 目前我只能做这个图 我希望两个系列图可以根据其
  • 全局 JavaScript 变量作用域:为什么这不起作用?

    所以我在玩 JavaScript 时遇到了我认为奇怪的事情 有谁能解释一下以下内容吗 我已将警报值作为评论包含在内 为什么 foo 中的第一个警报 msg 返回不明确的并不是outside var msg outside function
  • 使用 word_number 值对 javascript 数组进行排序

    如何对数组进行排序 var arr new Array word 12 word 59 word 17 这样我得到 word 12 word 17 word 59 Thanks 您需要编写一个排序方法 您可以编写任何您喜欢的方法 该方法在
  • 向下滚动时如何使图像移动?

    这是我想要实现的目标的示例 https www flambette com en https www flambette com en 我尝试过更改图像的 css 属性 但效果不能满足我的需求 我尝试过以下代码 mydocument on
  • 为什么新行上的 return 语句不返回任何值? [复制]

    这个问题在这里已经有答案了 考虑以下情况 function func1 return hello world function func2 return hello world console log func1 console log f
  • Javascript 根据字段值任意排序数组

    所以我有一个对象数组 如下所示 var myArray priority low priority critical priority high 我需要以这种方式排序 1 关键 2 高和3 低 如何才能做到这一点 我建议使用一个对象来存储排
  • contenteditable 在 safari 中不起作用,但在 chrome 中起作用

    我有一个奇怪的问题 这在 chrome 中按预期工作 但在 safari 中它只会发光 但不会对按键输入做出反应 这是触发文本版本的方法 var namebloc event currentTarget find column filena
  • 表单提交不起作用

    我有一张桌子 可以打印出所有可用的相机 它使用表单来更改这些设置 问题在于该表单仅更新条目中的最后一个摄像机 换句话说 如果我更改表单并为列表中的最后一个摄像机点击 应用 它将起作用 如果我更改此列表中任何其他摄像机的表单 它会将其更改为与
  • 函数声明或函数表达式

    我刚刚在块作用域中定义函数时遇到了问题 考虑以下程序 try greet function greet alert Merry Christmas catch error alert error 我希望这个程序能够发出警报Merry Chr
  • 检测 JavaScript 中的焦点丢失

    我希望能够检测 JavaScript 中任意元素何时失去焦点 因此我可以构建一个类似于 jEdit 的内联编辑工具 我不能依赖 jQuery 来实现这个库 所以我需要一个本机方法来完成它 我查看了 onblur 这似乎是正确的事情 但 MD
  • 传单 - 导入 Geojson - Angular 6

    我尝试将 GeoJson 文件导入到 Angular 的应用程序 6 中的传单中 通过这个解决方案 我的 geojson 是在 leafletmap 中绘制的 但我有这个错误 我无法构建我的应用程序 有人知道一种解决方案吗 错误 TS234
  • Javascript/DOM:如何删除 DOM 对象的所有事件侦听器?

    只是问题 有没有办法完全删除对象的所有事件 例如一个div 编辑 我添加每div addEventListener click eventReturner false 一个事件 function eventReturner return f
  • 尽管给出了供应商 ID,Web 串行 api 显示“未找到兼容设备”

    Windows 8 1 Chrome v91 0 4472 164 我已根据设备管理器验证了供应商和产品 ID 该设备是使用 Ch340 驱动程序的 Arduino UNO 它在设备管理器中的端口 COM 和 LPT 下列为 USB SER
  • Javascript 替换为正则表达式无法正常工作

    我正在尝试使用正则表达式验证名称 正则表达式阻止用户连续输入 2 个空格或点 这是我的代码 function test input var regex A Za z 0 1 s 0 1 input value input value rep
  • 使用重复模式捕获正则表达式

    我试图捕获字符串的所有部分 但我似乎无法正确处理 该字符串具有以下结构 1 22 33 中间有运算符的数字 可以有任意数量的术语 我想要的是 1 22 33 1 22 33 但我得到 1 22 33 22 33 我尝试过各种正则表达式 这是
  • 更改 CSS 样式表的选择器属性

    以下是我们传统上如何更改重复元素的样式 将样式应用到每个元素 function changeStyle selector prop val var elems document querySelectorAll selector Array
  • 当 jQuery .remove() 用于删除脚本标签时,它是否会清除加载的 JavaScript?

    正如标题所示 如果我使用以下命令从 DOM 中删除脚本标签 scriptid remove javascript 本身是保留在内存中还是被清除了 或者 我完全误解了浏览器处理 javascript 的方式吗 这是很有可能的 对于那些对我提问

随机推荐

  • 从内部存储中删除文件

    我正在尝试删除存储在内部存储中的图像 到目前为止我已经想出了这个 File dir getFilesDir File file new File dir id jpg boolean deleted file delete 这是来自另一个问
  • 上限集合性能问题

    我正在做一些测试 看看我可以从 Mongodb 获得什么样的吞吐量 文档说上限集合是最快的选择 但我经常发现我可以更快地写入普通集合 根据具体的测试 我通常可以通过正常收集获得两倍的吞吐量 我错过了什么吗 我该如何解决这个问题 我有一个非常
  • 检索超过 7 天的特定用户的推文

    我正在尝试获取任何用户的推文 但它只返回最近 7 天的推文 我想检索比这更旧的推文 如何做 现在我正在通过以下方式获取推文 http search twitter com search atom q from 3Amihirpmehta h
  • bash:Python 导入 - 找不到 pandas 命令

    我是使用 MacBook 的 Python 初学者 我想进口pandas在我的 Python 脚本中 我输入以下命令 import pandas as pd 结果是 错误 bash 导入 找不到命令 问题 如何启用导入命令 我用了 usr
  • @Qualifier 的问题

    我正在 Java Spring 环境中工作 并且在让 Qualifier 工作时遇到问题 我们项目的其他部分正在使用 Inject 来获取一个 bean 但我需要有同一个 bean 的两个版本 看起来使用 Autowired 和 Quali
  • 如何使用 Java 解析此 XML?

  • Telnet smtp.mail - 必须首先发出 STARTTLS 命令

    在我的 Mac 终端上 我试图telnet进入我的smtp gmail com通过port 587 在 Google Apps 设置为管理 Dreamhost 域 上 我配置了中继 如下所示 Allowed senders Only add
  • bash:提取路径名的最后两个目录

    我似乎在 bash 中失败了一些非常简单的事情 我有一个字符串变量 它保存目录的完整路径 我想分配最后一个two将其中的目录转换为另一个字符串 例如 如果我有 DIRNAME a b c d e 我想要 DIRNAME2 d e 我确信有一
  • 如何将带有 null 终止字符的字节数组转换为 Java 中的字符串?

    如何从字节数组创建 String 对象 byte arr MAX SIZE Java 其中数组元素之一是 C 空终止字节 是不是像打电话那么简单 String str new String arr String 构造函数是否知道自动停止在空
  • 在混合应用程序中,如何确认只有您的应用程序正在访问服务器端页面

    混合应用程序显然有点新 因此很难找到这方面的好信息 我知道我需要在服务器端页面上允许跨源资源共享 但这显然会增加安全缺陷 在phonegap cordova应用程序上 我只有通过ajax调用服务器端页面的客户端控制 这意味着任何人都可以访问
  • 在 OpenGL 中动态更改纹理

    我有一些生成图像的 OpenCV 代码 我使用 OpenGL 显示这些 创建新图像时 我使用相同的值运行以下函数 每次 texture名称和新的image void loadCVTexture GLuint texture const cv
  • Twilio - 响铃 2 次后转接呼叫

    是否可以使用 Twilio 将来电转移到电话号码 A 假设 416 555 1234 并且如果电话号码 A 占线或在响铃 2 或 3 次后无人接听 则转移到电话号码 B XML 现在看起来像这样
  • 如何检查 h2 数据库健康状况和损坏情况

    我在 JavaFX 8 桌面应用程序中以嵌入模式使用 h2 数据库 并且我为用户开发了一个选项来备份和恢复数据库文件 在旧版本的程序中 我使用了 SQLite 数据库 并且使用 pragmaintegrity check 命令检查数据库文件
  • 如何更改levatedButtonTheme中的ElevatedButton文本颜色?

    我正在尝试更改主题中levatedButtonTheme 属性中的ElevatedButton 文本颜色 但无法更改 我知道 Text 的子元素中的 TextStyle 可以更改 Text 的颜色 但我更喜欢在levedButtonThem
  • 什么是格洛姆?它与mapPartitions有何不同?

    我遇到过glom RDD 上的方法 根据文档 返回通过将每个分区内的所有元素合并到数组中创建的 RDD Does glom跨分区混洗数据还是仅将分区数据作为数组返回 在后一种情况下 我相信使用同样可以实现mapPartitions 我还想知
  • 如何在 mysql (laravel) 中使 varchar 可以为空且唯一

    我可以使 MySQL 列可以为空并且唯一吗 我有一个存储用户 Email id 的表 如果用户想提供的话 否则它将是 空 我在其他一些问题中读到我可以创建一个默认为 NULL 的唯一字段 但我在创建表时收到此错误 1067 Invalid
  • OS X cmake 找不到 PythonLibs 3.4

    python 和 python3 通过 Homebrew 安装在 OS X Yosemite 中 但 cmake 找不到 PythonLibs 3 只有 2 个 CMakeLists txt set Python ADDITIONAL VE
  • 从 Postgres JDBC 中的结果集中读取 UUID

    我正在使用 UUID 作为我的 id 列 我正在寻找一种方法来检索我的 Java 应用程序中的数据 我在 ResultSet 中找不到获取 UUID 的方法 我该如何获取 UUID 对于任何搜索的人来说 这是如何完成的 java util
  • 使用 OAuth 2.0 通过 SMACK Java 库进行 X-FACEBOOK-PLATFORM 身份验证

    第一次在这里发帖 所以请温柔 我正在使用 Smack 库构建一个 Facebook 聊天客户端 我正在使用 X FACEBOOK PLATFORM 方法 以免保存任何密码 我使用 oauth 1 0 使其正常工作 并想将其更改为 2 0 这
  • javascript for 循环内的异步过程[重复]

    这个问题在这里已经有答案了 我正在运行以下形式的事件循环 var i var j 10 for i 0 i lt j i asynchronousProcess callbackFunction alert i 我试图显示一系列显示数字 0