nodejs for循环 异步是异步的吗

求讲解for循环里再进行for循环是怎么执行的
[问题点数:20分,结帖人spg120]
求讲解for循环里再进行for循环是怎么执行的
[问题点数:20分,结帖人spg120]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|如何用Promise控制for循环的异步流程?(已解决) - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
初学者,实在搞不清楚了,请教各位
问题写在注释里了
补充,大致知道咋回事了,for循环里面还有一个数据库查询,两个异步嵌套,立马就懵逼了
解决方案在后面,往下拉
// 有学校、部门两个表,学校表字段是id name,部门表的字段是id name school_id
// 获取学校列表,然后根据学校id去查询每个学校下的部门数量,再给每个学校增加部门数量depNum,组成新的学校对象,字段有id name depNum,然后渲染模板
var listSchools = async () =& {
return new Promise((resolve, reject)=& {
pool.query('SELECT * FROM schools', function (err, rows) {
if (err) {
console.log(err);
reject(err);
resolve(rows);
// 现在卡在这一步了,不知道怎么实现先for循环获取到部门数量之后再渲染模板
// 也就是说不知道怎么用Promise写for循环
var listDepartments = async schools =& {
for(let school of schools){
pool.query(‘SELECT * FROM departments WHERE school_id = ?’, , function(err, rows) {
school.depNum = rows. //获取每个学校的部门数量
listSchools().then(listDepartments).then(//渲染模板).catch(err=&{console.log(err)})
感谢楼下的指点,问题已经解决了,贴出最终代码
es6 promise.all
看你的代码已经用上了async,那么我给你写一个使用ES7 async的方式实现的例子:
function sleep(t) {
return new Promise((resolve, reject) =& {
setTimeout(function () {
resolve();
}, t * 1000);
(async function test() {
for (var i = 1; i & 10; i++) {
await sleep(i);
console.log(i);
也可以看看
只看到你用async, 你把await呢?
用then了好像不需要await?晕菜了已经,刚学后端就挑了个异步的学
好像是这个能解决,我试一下,谢谢!朋友告诉我查询数据库根本不要这样查,直接join查询出统计结果就行了
用了async/await还要用then?
成功了!谢谢
因为await里面嵌套了一个异步,await无效
循环用Promise.all,在循环上我也没有找到用async/await 更好的处理方法。。。
看我主楼的更新,你用的Promise.all是第三方库的用法吗?我不大想用第三方,用不了几天就过时了
bluebird 过时还要些日子的吧
蓝鸟写起来比我这个能简化很多不
写法上差的不是太多,
但是个人觉得:但是思路方面可以流畅很多,更容易让人理解。
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的45被浏览3,504分享邀请回答4添加评论分享收藏感谢收起var array=[1,2,3,4,5,6,7,8,9]
function loop(callback){
array.length!==0 ? (callback(array.shift()),loop(callback)) : console.log('Loop End!')
loop(function(arg){
console.log(arg)
013 条评论分享收藏感谢收起写回答ES6与for循环
时间: 13:54:16
&&&& 阅读:2223
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&部分内容供参自:&
在ECMAScript5(简称 ES5)中,有三种 for 循环,分别是:
简单for循环
在2015年6月份发布的ECMAScript6(简称 ES6)中,新增了一种循环,是:
下面我们就来看看这 4 种 for 循环。
简单 for 循环
下面先来看看大家最常见的一种写法:
const arr = [1, 2, 3];
for(let i = 0; i & arr. i++) {
&&&&console.log(arr[i]);
当数组长度在循环过程中不会改变时,我们应将数组长度用变量存储起来,这样会获得更好的效率,下面是改进的写法:
const arr = [1, 2, 3];
for(let i = 0, len = arr. i & i++) {
&&&&console.log(arr[i]);
通常情况下,我们可以用 for-in 来遍历一遍数组的内容,代码如下:
const arr = [1, 2, 3];
for(index in arr) {
&&&&console.log("arr[" + index + "] = " + arr[index]);
一般情况下,运行结果如下:
arr[0] = 1
arr[1] = 2
arr[2] = 3
但这么做往往会出现问题。
for-in 的真相
for-in 循环遍历的是对象的属性,而不是数组的索引。因此, for-in 遍历的对象便不局限于数组,还可以遍历对象。例子如下:
const person = {
&&&&fname: "san",
&&&&lname: "zhang",
&&&&age: 99
for(info in person) {
&&&&console.log("person[" + info + "] = " + person[info]);
结果如下:
person[fname] = san
person[lname] = zhang
person[age] = 99
需要注意的是, for-in 遍历属性的顺序并不确定,即输出的结果顺序与属性在对象中的顺序无关,也与属性的字母顺序无关,与其他任何顺序也无关。
Array 的真相
Array 在 Javascript 中是一个对象, Array 的索引是属性名。事实上, Javascript 中的 “array” 有些误导性, Javascript 中的 Array 并不像大部分其他语言的数组。首先, Javascript 中的 Array 在内存上并不连续,其次, Array 的索引并不是指偏移量。实际上, Array 的索引也不是 Number 类型,而是 String 类型的。我们可以正确使用如 arr[0] 的写法的原因是语言可以自动将 Number 类型的 0 转换成 String 类型的 “0″ 。所以,在 Javascript 中从来就没有 Array 的索引,而只有类似 “0″ 、 “1″ 等等的属性。有趣的是,每个 Array 对象都有一个 length 的属性,导致其表现地更像其他语言的数组。但为什么在遍历 Array 对象的时候没有输出 length 这一条属性呢?那是因为 for-in 只能遍历“可枚举的属性”, length 属于不可枚举属性,实际上, Array 对象还有许多其他不可枚举的属性。
现在,我们再回过头来看看用 for-in 来循环数组的例子,我们修改一下前面遍历数组的例子:
const arr = [1, 2, 3];
arr.name = "Hello world";
for(index in arr) {
&&&&console.log("arr[" + index + "] = " + arr[index]);
运行结果是:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[name] = Hello world
我们看到 for-in 循环访问了我们新增的 “name” 属性,因为 for-in 遍历了对象的所有属性,而不仅仅是“索引”。同时需要注意的是,此处输出的索引值,即 “0″、 “1″、 “2″不是 Number 类型的,而是 String 类型的,因为其就是作为属性输出,而不是索引。那是不是说不在我们的 Array 对象中添加新的属性,我们就可以只输出数组中的内容了呢?答案是否定的。因为 for-in 不仅仅遍历 array 自身的属性,其还遍历 array 原型链上的所有可枚举的属性。下面我们看个例子:
Array.prototype.fatherName = "Father";
const arr = [1, 2, 3];
arr.name = "Hello world";
for(index in arr) {
&&&&console.log("arr[" + index + "] = " + arr[index]);
运行结果是:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[name] = Hello world
arr[fatherName] = Father
写到这里,我们可以发现 for-in 并不适合用来遍历 Array 中的元素,其更适合遍历对象中的属性,这也是其被创造出来的初衷。却有一种情况例外,就是稀疏数组。考虑下面的例子:
const arr = [];
arr[0] = "a";
arr[100] = "b";
arr[10000] = "c";
for(key in arr) {
&&&&if(arr.hasOwnProperty(key)& &&&&&
&&&&&&&&/^0$|^[1-9]\d*$/.test(key) &&&&&
&&&&&&&&key &= &&&&&&&&&&&&&&
&&&&&&&&) {
&&&&&&&&console.log(arr[key]);
for-in 只会遍历存在的实体,上面的例子中, for-in 遍历了3次(遍历属性分别为”0″、 “100″、 “10000″的元素,普通 for 循环则会遍历 10001 次)。所以,只要处理得当, for-in 在遍历 Array 中元素也能发挥巨大作用。
为了避免重复劳动,我们可以包装一下上面的代码:
function arrayHasOwnIndex(array, prop) {
&&&&return array.hasOwnProperty(prop) &&
&&&&&&&&/^0$|^[1-9]\d*$/.test(prop) &&
&&&&&&&&prop &= ;
使用示例如下:
for (let key in arr) {
&&&&if (arrayHasOwnIndex(arr, key)) {
&&&&&&&&console.log(arr[key]);
for-in 性能
正如上面所说,每次迭代操作会同时搜索实例或者原型属性, for-in 循环的每次迭代都会产生更多开销,因此要比其他循环类型慢,一般速度为其他类型循环的 1/7。因此,除非明确需要迭代一个属性数量未知的对象,否则应避免使用 for-in 循环。如果需要遍历一个数量有限的已知属性列表,使用其他循环会更快,比如下面的例子:
const obj = {
&&&&"prop1": "value1",
&&&&"prop2": "value2"
const props = ["prop1", "prop2"];
for(let i = 0; i & props. i++) {
&&&&console.log(obj[props[i]]);
上面代码中,将对象的属性都存入一个数组中,相对于 for-in 查找每一个属性,该代码只关注给定的属性,节省了循环的开销和时间。
在 ES5 中,引入了新的循环,即 forEach 循环。
const arr = [1, 2, 3];
arr.forEach((data) =& {
&&&&console.log(data);
运行结果:
forEach 方法为数组中含有有效值的每一项执行一次 callback 函数,那些已删除(使用 delete 方法等情况)或者从未赋值的项将被跳过(不包括那些值为 undefined 或 null 的项)。 callback 函数会被依次传入三个参数:
数组当前项的值;
数组当前项的索引;
数组对象本身;
需要注意的是,forEach 遍历的范围在第一次调用 callback 前就会确定。调用forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。已删除的项不会被遍历到。
const arr = [];
arr[0] = "a";
arr[3] = "b";
arr[10] = "c";
arr.name = "Hello world";
arr.forEach((data, index, array) =& {
&&&&console.log(data, index, array);
运行结果:
a 0 ["a", 3: "b", 10: "c", name: "Hello world"]
b 3 ["a", 3: "b", 10: "c", name: "Hello world"]
c 10 ["a", 3: "b", 10: "c", name: "Hello world"]
这里的 index 是 Number 类型,并且也不会像 for-in 一样遍历原型链上的属性。
所以,使用 forEach 时,我们不需要专门地声明 index 和遍历的元素,因为这些都作为回调函数的参数。
另外,forEach 将会遍历数组中的所有元素,但是 ES5 定义了一些其他有用的方法,下面是一部分:
every: 循环在第一次 return false 后返回
some: 循环在第一次 return true 后返回
filter: 返回一个新的数组,该数组内的元素满足回调函数
map: 将原数组中的元素处理后再返回
reduce: 对数组中的元素依次处理,将上次处理结果作为下次处理的输入,最后得到最终结果。
forEach 性能
首先感谢@papa pa的提醒,才发现我之前的理解有错误。
大家可以看 jsPerf ,在不同浏览器下测试的结果都是 forEach 的速度不如 for。如果大家把测试代码放在控制台的话,可能会得到不一样的结果,主要原因是控制台的执行环境与真实的代码执行环境有所区别。
先来看个例子:
const arr = [‘a‘, ‘b‘, ‘c‘];
for(let data of arr) {
&&&&console.log(data);
运行结果是:
为什么要引进 for-of?
要回答这个问题,我们先来看看ES6之前的 3 种 for 循环有什么缺陷:
forEach 不能 break 和 return;
for-in 缺点更加明显,它不仅遍历数组中的元素,还会遍历自定义的属性,甚至原型链上的属性都被访问到。而且,遍历数组元素的顺序可能是随机的。
所以,鉴于以上种种缺陷,我们需要改进原先的 for 循环。但 ES6 不会破坏你已经写好的 JS 代码。目前,成千上万的 Web 网站依赖 for-in 循环,其中一些网站甚至将其用于数组遍历。如果想通过修正 for-in 循环增加数组遍历支持会让这一切变得更加混乱,因此,标准委员会在 ES6 中增加了一种新的循环语法来解决目前的问题,即 for-of 。
那 for-of 到底可以干什么呢?
跟 forEach 相比,可以正确响应 break, continue, return。
for-of 循环不仅支持数组,还支持大多数类数组对象,例如 DOM nodelist 对象。
for-of 循环也支持字符串遍历,它将字符串视为一系列 Unicode 字符来进行遍历。
for-of 也支持 Map 和 Set (两者均为 ES6 中新增的类型)对象遍历。
总结一下,for-of 循环有以下几个特征:
这是最简洁、最直接的遍历数组元素的语法。
这个方法避开了 for-in 循环的所有缺陷。
与 forEach 不同的是,它可以正确响应 break、continue 和 return 语句。
其不仅可以遍历数组,还可以遍历类数组对象和其他可迭代对象。
但需要注意的是,for-of循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用for-in 循环(这也是它的本职工作)。
最后要说的是,ES6 引进的另一个方式也能实现遍历数组的值,那就是 Iterator。上个例子:
const arr = [‘a‘, ‘b‘, ‘c‘];
const iter = arr[Symbol.iterator]();
iter.next()
iter.next()
iter.next()
iter.next()
前面的不多说,重点描述for-of
for-of循环不仅支持数组,还支持大多数类数组对象,例如DOM&。
for-of循环也支持字符串遍历,它将字符串视为一系列的Unicode字符来进行遍历:
window.onload=function(){&
& &const arr = [55,00, 11, 22];
& &arr.name = "hello";
& // Array.prototype.FatherName = ‘FatherName‘;
& &/*for(let key in arr){
& & console.log(‘key=‘+key+‘,key.value=‘+arr[key]);
& &/* arr.forEach((data) =& {console.log(data);});*/
& /* arr.forEach((data,index,arr) =& {console.log(data+‘,‘+index+‘,‘+arr);});*/
& /*for(let key of arr){
& & console.log(key);
& var string1 = ‘abcdefghijklmn‘;
& var string2 = ‘opqrstuvwxyc‘;
& const stringArr = [string1,string2];
& for(let key of stringArr){
& & console.log(key);
& for(let key of string1){
& & console.log(key);
现在,只需记住:
这是最简洁、最直接的遍历数组元素的语法
这个方法避开了for-in循环的所有缺陷
与forEach()不同的是,它可以正确响应break、continue和return语句
for-in循环用来遍历对象属性。
for-of循环用来遍历数据—例如数组中的值。
它同样支持Map和Set对象遍历。
Map和Set对象是ES6中新增的类型。ES6中的Map和Set和java中并无太大出入。
Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。
要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:
var s1 = new Set();
重复元素在Set中自动被过滤:
var s = new Set([1, 2, 3, 3, ‘3‘]);
s; // Set {1, 2, 3, "3"}
通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:
var s = new Set([1, 2, 3]);
通过delete(key)方法可以删除元素:
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
Set对象可以自动排除重复项
var string1 = ‘abcdefghijklmn‘;
& var string2 = ‘opqrstuvwxyc‘;
& var string3 = ‘opqrstuvwxyc‘;
& var string4 = ‘opqrstuvwxyz‘;
& const stringArr = [string1,string2,string3,string4];
&var newSet = new Set(stringArr);
& for(let key of newSet){
& & console.log(key);
Map对象稍有不同:内含的数据由键值对组成,所以你需要使用解构(destructuring)来将键值对拆解为两个独立的变量:
for (var [key, value] of phoneBookMap) {
console.log(key + "‘s phone number is: " + value);
&var m = new Map([[1, ‘Michael‘], [2, ‘Bob‘], [3, ‘Tracy‘]]);
& var map = new Map([[‘1‘,‘Jckey‘],[‘2‘,‘Mike‘],[‘3‘,‘zhengxin‘]]);
& map.set(‘4‘,‘Adam‘);//添加key-value
& map.set(‘5‘,‘Tom‘);
& map.set(‘6‘,‘Jerry‘);
& console.log(map.get(‘6‘));
& map.delete(‘6‘);
& &console.log(map.get(‘6‘));
& for(var [key,value] of map) {
& & console.log(‘key=‘+key+‘ , value=‘+value);
解构也是ES6的新特性,我们将在另一篇文章中讲解。看来我应该记录这些优秀的主题,未来有太多的新内容需要一一剖析。
现在,你只需记住:未来的JS可以使用一些新型的集合类,甚至会有更多的类型陆续诞生,而for-of就是为遍历所有这些集合特别设计的循环语句。
for-of循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用for-in循环(这也是它的本职工作)或内建的Object.keys()方法:
of Object.keys(someObject)){
console.log(key +": "+ someObject[key]);
var obj = { name :‘name‘, age : ‘age‘, sex : ‘sex‘ }; for (var key of Object.keys(obj)) { console.log(key + ": " + obj[key]); }
“能工摹形,巧匠窃意。”——巴勃罗·毕卡索
ES6始终坚持这样的宗旨:凡是新加入的特性,势必已在其它语言中得到强有力的实用性证明。
举个例子,新加入的for-of循环像极了C++、Java、C#以及Python中的循环语句。与它们一样,这里的for-of循环支持语言和标准库中提供的几种不同的数据结构。它同样也是这门语言中的一个扩展点(译注:关于扩展点,建议参考 1.&&2.&)。
正如其它语言中的for/foreach语句一样,for-of循环语句通过方法调用来遍历各种集合。数组、Maps对象、Sets对象以及其它在我们讨论的对象有一个共同点,它们都有一个迭代器方法。
你可以给任意类型的对象添加迭代器方法。
当你为对象添加myObject.toString()方法后,就可以将对象转化为字符串,同样地,当你向任意对象添加myObject[Symbol.iterator]()方法,就可以遍历这个对象了。
举个例子,假设你正在使用jQuery,尽管你非常钟情于里面的.each()方法,但你还是想让jQuery对象也支持for-of循环,你可以这样做:
好的,我知道你在想什么,那个[Symbol.iterator]语法看起来很奇怪,这段代码到底做了什么呢?这里通过Symbol处理了一下方法的名称。标准委员会可以把这个方法命名为.iterator()方法,但是如果你的代码中的对象可能也有一些.iterator()方法,这一定会让你感到非常困惑。于是在ES6标准中使用symbol来作为方法名,而不是使用字符串。
你大概也猜到了,Symbols是ES6中的新类型,我们会在后续的文章中讲解。现在,你需要记住,基于新标准,你可以定义一个全新的symbol,就像Symbol.iterator,如此一来可以保证不与任何已有代码产生冲突。这样做的代价是,这段代码的语法看起来会略显生硬,但是这微乎其微代价却可以为你带来如此多的新特性和新功能,并且你所做的这一切可以完美地向后兼容。
所有拥有[Symbol.iterator]()的对象被称为可迭代的。在接下来的文章中你会发现,可迭代对象的概念几乎贯穿于整门语言之中,不仅是for-of循环,还有Map和Set构造函数、解构赋值,以及新的展开操作符。
迭代器对象
现在,你将无须亲自从零开始实现一个对象迭代器,我们会在下一篇文章详细讲解。为了帮助你理解本文,我们简单了解一下迭代器(如果你跳过这一章,你将错过非常精彩的技术细节)。
for-of循环首先调用集合的[Symbol.iterator]()方法,紧接着返回一个新的迭代器对象。迭代器对象可以是任意具有.next()方法的对象;for-of循环将重复调用这个方法,每次循环调用一次。举个例子,这段代码是我能想出来的最简单的迭代器:
var zeroesForeverIterator = {
[Symbol.iterator]: function () {
return this;
next: function () {
return {done: false, value: 0};
每一次调用.next()方法,它都返回相同的结果,返回给for-of循环的结果有两种可能:(a) 我们尚未完成迭代;(b) 下一个值为0。这意味着(value of zeroesForeverIterator) {}将会是一个无限循环。当然,一般来说迭代器不会如此简单。
这个迭代器的设计,以及它的.done和.value属性,从表面上看与其它语言中的迭代器不太一样。在Java中,迭代器有分离的.hasNext()和.next()方法。在Python中,他们只有一个.next() 方法,当没有更多值时抛出StopIteration异常。但是所有这三种设计从根本上讲都返回了相同的信息。
迭代器对象也可以实现可选的.return()和.throw(exc)方法。如果for-of循环过早退出会调用.return()方法,异常、break语句或return语句均可触发过早退出。如果迭代器需要执行一些清洁或释放资源的操作,可以在.return()方法中实现。大多数迭代器方法无须实现这一方法。.throw(exc)方法的使用场景就更特殊了:for-of循环永远不会调用它。但是我们还是会在下一篇文章更详细地讲解它的作用。
现在我们已了解所有细节,可以写一个简单的for-of循环然后按照下面的方法调用重写被迭代的对象。
首先是for-of循环:
for (VAR of ITERABLE) {
然后是一个使用以下方法和少许临时变量实现的与之前大致相当的示例,:
var $iterator = ITERABLE[Symbol.iterator]();
var $result = $iterator.next();
while (!$result.done) {
VAR = $result.value;
$result = $iterator.next();
这段代码没有展示.return()方法是如何处理的,我们可以添加这部分代码,但我认为这对于我们正在讲解的内容来说过于复杂了。for-of循环用起来很简单,但是其背后有着非常复杂的机制。
我何时可以开始使用这一新特性?
目前,对于for-of循环新特性,所有最新版本Firefox都(部分)支持(译注:从FF 13开始陆续支持相关功能,FF 36 - FF 40基本支持大部分特性),在Chrome中可以通过访问 chrome://flags 并启用“实验性JavaScript”来支持。微软的Spartan浏览器支持,但是IE不支持。如果你想在web环境中使用这种新语法,同时需要支持IE和Safari,你可以使用或Google的这些编译器来将你的ES6代码翻译为Web友好的ES5代码。
而在服务端,你不需要类似的编译器,io.js中默认支持ES6新语法(部分),在Node中需要添加--harmony选项来启用相关特性。
{done: true}
好的,我们今天的讲解就到这里,但是对于for-of循环的使用远没有结束。
在ES6中有一种新的对象与for-of循环配合使用非常契合,我没有提及它因为它是我们下周文章的主题,我认为这种新特性是ES6种最梦幻的地方,如果你尚未在类似Python和C#的语言中遇到它,你一开始很可能会发现它令人难以置信,但是这是编写迭代器最简单的方式,在重构中非常有用,并且它很可能改变我们书写异步代码的方式,无论是在浏览器环境还是服务器环境,所以,下周的深入浅出 ES6 中,请务必一起来仔细看看 ES6 的生成器:generators。
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文地址:http://www.cnblogs.com/dougest/p/6604427.html
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!详解JavaScript for循环中发送AJAX请求问题
转载 & & 投稿:lijiao
这篇文章主要为大家剖析了JavaScript for循环中发送AJAX请求问题,感兴趣的小伙伴们可以参考一下
首先说,出现这个问题的场景是很少见的,因为有太多更好解决方法。今天搞ajax的时候,一个有趣的地方,,每个迭代中都要发送一个get请求,因为迭代的速度太快,一个请求还没有完成就进行下一个迭代,在chrome和ff上,除最后一个请求外,其它请求都被取消了。所以该怎么办呢?设置延时(不太好)还是其他办法?
&办法有很多,比如设置休眠,迭代等等, 我采用的是另外两种解决办法。
&一、同步的ajax请求,而ajax请求默认是异步的,所以要设置为false。
function creatXMLHttpRequest() {
if (window.ActiveXObject) {
return xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
return xmlHttp = new XMLHttpRequest();
function disButton(name, actionName, resquestParmName) {
var path = document.getElementById("path").
var xmlHttp = creatXMLHttpRequest();
var invoiceIds = new Array();
invoiceIds = document.getElementsByName(name);
// 迭代的速度快于发送请求+收到回复的时间 所以一次get请求都还没有完成就进行了下一次请求
for (i = 0; i & invoiceIds. i++) {
var invoiceId = invoiceIds[i].
var url = path + "/" + actionName + ".action?" + resquestParmName + "="
+ invoiceId;
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var result = xmlHttp.responseT
if (result == "0") {
document.getElementById("btn" + invoiceId).disabled = "disabled";
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
这样,用同步的ajax请求,就会等服务器响应后,执行完代码,再继续迭代。但是好像不推荐这样做。
二、采用异步的方式,但要记住,每次迭代都要创建一个新XMLHttpRequest对象,不能重用。
function creatXMLHttpRequest() {
if (window.ActiveXObject) {
return xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
return xmlHttp = new XMLHttpRequest();
function disButton(name, actionName, resquestParmName) {
var path = document.getElementById("path").
var invoiceIds = new Array();
invoiceIds = document.getElementsByName(name);
// 迭代的速度快于发送请求+收到回复的时间 所以一次get请求都还没有完成就进行了下一次请求
for (i = 0; i & invoiceIds. i++) {
xmlHttp = creatXMLHttpRequest();
var invoiceId = invoiceIds[i].
var url = path + "/" + actionName + ".action?" + resquestParmName + "="
+ invoiceId;
fu(xmlHttp,url,invoiceId);
function fu(xmlHttp,url,invoiceId){
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var result = xmlHttp.responseT
if (result == "0") {
document.getElementById("btn" + invoiceId).disabled = "disabled";
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
由于JS的for循环与ajax非同步运行,因此导致for循环结束了而ajax却还未执行。如果采用的是异步请求的方式,如果每次迭代的时候都去new一个XMLHttpRequest,这样每次请求都能完成,但是结果还是还是不准确,有些程序还未被执行。
明白了,原来是每次迭代去执行几行代码,应该把发送ajax异步请求的代码放在一个函数中,每次迭代就去调用这个函数,这样就行了。
性能上,对于这种迭代ajax请求,似乎同步的方式性能更高。
这个问题解决了,也加深了对ajax、http的理解。
以上就介绍了JavaScript for循环中发送AJAX请求的问题,希望对Javascript教程有兴趣的朋友有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 for循环是异步吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信