js中ajax的异步执行与同步执行

@(笔记)[ajax]

工作中的问题

在循环之前给元素标记一种状态,然后执行循环体每一次循环都有一次ajax请求,循环结束之后恢复元素状态。

代码块

html

<ul>
	<li><button id="getinfo">获取信息</button></li>
	<li><button id="getnext">获取下一个</button></li>
	<li id="info">
		<p>信息替换</p>
		<p>信息替换</p>
		<p>信息替换</p>
	</li>
</ul>

循环开始之前运行的方法

function ajaxStart() {
	console.log("ajaxStart");
	$("#getnext").html("获取中。。。");
} > **循环体** ajax同步

function ajaxMain() {
	$('p').each(function() {
		//setTimeout(function() {
			$.ajax({
				type: "get",
				url: "../json/js_asyn.json",
				async: false,
				success: function(data) {
					console.log('ajaxMain');
				}
			});
		//}, 2000);
	});
} > **循环结束** 

function ajaxEnd() {
	console.log('ajaxEnd');
	$("#getnext").html("获取成功");
} > **执行代码**

$("#getnext").click(function() {
	ajaxStart();
	ajaxMain();
	ajaxEnd();
}); > 输出结果   UI渲染过程的效果不明显 ,**实际上UI渲染被阻塞$('getnext').html('获取中。。。')不能及时更新,而是等待ajaxMain函数打印完结果后再执行。必须让ajaxMain延时执行,UI才能及时更新,$('getnext').html('获取中。。。')可立即执行,同时ajaxEnd也会跟着执行。最后执行ajaxMain。**

"ajaxStart"	
"ajaxMain"	
"ajaxMain"	
"ajaxMain"
"ajaxEnd"	 > 如果ajax异步   输出结果   UI渲染过程的效果不明显

"ajaxStart"	
"ajaxEnd"	
"ajaxMain"	
"ajaxMain"	
"ajaxMain"

如果ajax延时2s执行 输出结果

"ajaxStart"	
"ajaxEnd"	
"ajaxMain"	
"ajaxMain"	
"ajaxMain"

如何才能在ajaxMain全部执行完之后再执行ajaxEnd?直接把ajaxEnd放到ajax成功时的代码内,肯定不行,第一次成功就会执行ajaxEnd,必须在每一次成功时记录一次状态,并在下一次成功时获取这个状态,直到传递到最后一个ajax成功时再执行ajaxEnd。


最后ajaxMian

function ajaxMain() {
	var num = 0;
	var plen = $("p").length;
	$('p').each(function() {
		var self = $(this);
		setTimeout(function() {
			$.ajax({
				type: "get",
				url: "../json/js_asyn.json",
				async: false,
				success: function(data) {
					console.log('ajaxMain');
					self.html('替换成功');
					num = ++num;
					if (num = plen) {
						ajaxEnd();
					}
				}
			});
		}, 200);
	});
}

参考了以下代码,复习了ajax同步异步编程知识

代码块

html

<div id="output"></div>
<button onclick="updateSync ()">Run Sync</button>
<button onclick="updateAsync ()">Run Async</button> > js

function updateSync() {

    for (var i = 0; i < 1000; i++) {
        document.getElementById('output').innerHTML = i;
    }
    
}
function updateAsync() {

    var i = 0;
    function updateLater() {
        document.getElementById('output').innerHTML = (i++);
        if (i < 1000) {
            setTimeout(updateLater, 0);
        }
    }
    updateLater();
    
}

由于js是单线程的所以运行updateSync函数导致UI更新被阻塞,setTimeout让updateLater函数异步执行,可以看到看到UI界面上从0到999快速地更新过程。

代码块

function synchronizedCode() {

    var last = new Date().getTime();
    var count = 0;
    while (true) {
        var now = new Date().getTime();
        if (now - last > 1000 * 2) {
            last = now;
            count++;
            console.log('the '+count+'th count');
        }
        if (count > 5) {
            console.log('exist while.');
            break;
        }
    }
    
}

(function() {

    setTimeout(function() {console.log('setTimeout 0 occured first.');},0);
    setTimeout(function() {console.log('setTimeout 0 occured second.');},0);
    
    synchronizedCode();
    
})();

输出结果

the 1th count.

the 2th count.

the 3th count.

the 4th count.

the 5th count.

exist while.

setTimeout 0 occured first.

setTimeout 0 occured second.

使用setTimeout函数时,尽管延时为0,js的执行顺序还是发生了改变。

参考文件

22 Jul 2016

| 本文访问量:

上一篇 markdown学习笔记(一) 下一篇 markdown学习笔记(二)