`

如何在JavaScript中实现某个方法执行超时后则继续执行其它方法?

    博客分类:
  • RIA
阅读更多
我的一个想法是这样的,如下代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JavaScript方法执行超时测试</title>
<script>
	var executed = false; // 方法B是否执行的标志位
	var x = 0; // 方法A中用来累加计数,使方法A执行超时
	var expiredTime = 3000;
	
	// 方法A
	function methodA( )
	{
		// 第一句就执行定时器
		setTimeout("methodB()",expiredTime);// setInterval()
		// 方法A的耗时内容执行开始
		x = x + 1;
		document.counter.displayBox.value = x;
		for(i = 0;i < 80000;i++)
		{
			window.status = "i=" + i;
		}
		// 方法A的耗时内容执行结束
		
		// 当方法A的耗时内容没有超过expiredTime的时间执行完成的话,就直接开始执行方法B
		methodB();
		// 设置方法B执行完成的标志位
		executed = true;
	}

	// 方法B
	function methodB()
	{
		if(executed == true)
		{
			// 执行过了......
		}
		else
		{
			// 执行......
		}
	}
</script>
</head>

<body>
<form name="counter">
	<input type="text" name="displayBox" value="0" size="10"/>
</form>

<script>
methodA();
</script>

</body>
</html>


异想天开,想用 setTimeout 来做个 workaround ,但是 setTimeout / setInterval 方法是在它所在的方法执行完之后才开始计时的,于是,光当一声,这个 workaround 不成立。
各位有没有做过类似的需求,如何解决的呢?
分享到:
评论
37 楼 andyhu1007 2008-07-03  
afcn0 写道
首先js是单线程的,lz的想法就不对,那是多线程,现在基本除了XHR的callback可以另开一个线程以外,还无法实现多线程,其次timeout是在本次js代码运行完开始计时timeout的,所以在一个耗时的函数之外timeout或者interval一个函数运行本身就是荒谬的,ie下面alert,js函数执行也会阻塞interval执行,应该其他浏览器也是这么实现,我没测试,如果interval可以实现多线程,那至少ie上面也不行


js是单线程的没错,但是setTimeout确实可以解决这个问题。因为IE识别javascript是否running过长,是对每个event触发的javascript method而言。所以,分离出独立的方法,用setTimeout触发,确实可以让IE不要跳出那个可恶的error。当然,本质上没有减少运行的总体时间。
36 楼 xqstation 2008-06-12  
貌似你执行某个方法 fun1();
估计其应该只执行30秒,如果超了。这个方法结束。执行另一个方法?

但是fun1还是在执行啊。
并且IE会挂掉的。。。
35 楼 cbhyk 2007-11-13  
一切都是因为Windows程序是消息驱动的,看以下Windows程序的代码:

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
		PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT ("HelloWin") ;
	HWND	hwnd ;
	MSG	msg ;
	WNDCLAS	wndclass ;
	
	wndclass.style		  = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc  = WndProc ;
	wndclass.cbClsExtra	  = 0 ;
	wndclass.cbWndExtra	  = 0 ;
	wndclass.hInstance	  = hInstance ;
	wndclass.hIcon		  = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor	  = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuNam	= NULL ;
	wndclass.lpszClassName	= szAppName ;

	if (!RegisterClass (&wndclass))
	{
		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),  szAppName, MB_ICONERROR) ;
		return 0 ;
	}
	hwnd = CreateWindow( szAppName,	// window class name
			TEXT ("The Hello Program"),	// window caption
			WS_OVERLAPPEDWINDOW,	// window style
			CW_USEDEFAULT,	// initial x position
			CW_USEDEFAULT,	// initial y position
			CW_USEDEFAULT,	// initial x size
			CW_USEDEFAULT,	// initial y size
			NULL,			// parent window handle
			NULL,	        // window menu handle
			hInstance,	    // program instance handle
			NULL) ; 	    // creation parameters
	
	ShowWindow (hwnd, iCmdShow) ; // Post Message WM_SHOW
	UpdateWindow (hwnd) ;   // Post Message WM_PAINT, 这里可能不对
	
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC			hdc ;
	PAINTSTRUCT ps ;
	RECT		rect ;
	
	switch (message)
	{
		case WM_CREATE:
			return 0 ;
		
		case 	WM_PAINT:
			hdc = BeginPaint (hwnd, &ps) ;
			
			GetClientRect (hwnd, &rect) ;
			
			DrawText (hdc, TEXT ("Hello, World!"), -1, &rect,
			DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
			EndPaint (hwnd, &ps) ;
			return 0 ;
		
		case	WM_DESTROY:
			PostQuitMessage (0) ;
			return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}


一个Windows程序的入口是WinMain,这里面主要部分就是一个消息循环。IE用window.open的时候没有创建新进程,所以所有的消息都是主窗口的消息处理循环在处理。IE打开一个新窗口的时候所做的事情大概就是CreateWindow、ShowWindow、UpdateWindow,这三个方法里面并不是直接显示新窗口,而时往消息队列里面放WM_SHOW、WM_PAINT等消息,要到主消息循环处理到这些消息时才显示新窗口。

另外,setTimer,setInterval也只是让系统在若干时间后放一个WM_TIMER消息到消息队列,主消息循环处理到这个消息时才会运行setTimer和setInterval时指定的回调函数。
34 楼 YuLimin 2007-11-12  
感谢这么多人的热烈讨论,下面的代码是我继原贴后写的测试代码,大家可以在IE、FireFox、Opera等浏览器里测试一下看看结果。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JavaScript方法执行超时测试</title>
<script>
	var executed = false; // 方法B是否执行的标志位
	var x = 0; // 方法A中用来累加计数,使方法A执行超时
	var expiredTime = 2000;

	function methodMain()
	{
		expiredTime = 1000 * document.counter.expiredTime.value;
		var t = setInterval("methodA()",0);// setInterval()
		//clearTimeout
		setInterval("methodB()",expiredTime);// setInterval() setTimeout
		//clearInterval
	}

	// 方法A
	function methodA()
	{
		// 记下methodA执行的开始时间
		document.counter.aBegin.value = getNow();
		var loopSize = document.counter.loopSize.value;
		// 方法A的耗时内容执行开始
		for(i = 0;i <= loopSize;i++)
		{
			document.counter.displayBoxA.value = "i=" + i;
		}
		// 方法A的耗时内容执行结束

		// 当方法A的耗时内容没有超过expiredTime的时间执行完成的话,就直接开始执行方法B
		methodB();
		// 设置方法B执行完成的标志位
		executed = true;
		// 记下methodA执行的结束时间
		document.counter.aEnd.value = getNow()
	}

	// 方法B
	function methodB()
	{
		// 记下methodB执行的开始时间
		document.counter.bBegin.value = getNow();
		if(executed == true)
		{
			// 执行过了......
			// document.counter.displayBox.value = '执行过了......';
		}
		else
		{
			for(var i = 0;i < 100;i++)
			{
				x = x + 1;
				document.counter.displayBoxB.value = x;
			}
		}
		// 记下methodB执行的结束时间
		document.counter.bEnd.value = getNow()
	}

	function getNow()
	{
		var now = new Date();
        var year = now.getYear();
        var month = now.getMonth();
        var day = now.getDay();
        var hour = now.getHours();
        var minute = now.getMinutes();
        var second = now.getSeconds();

		// return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
		return new Date().format("yyyy-MM-dd hh:mm:ss");
	}

	Date.prototype.format = function(format)
	{
		var o =
		{
			"M+" : this.getMonth()+1, //month
			"d+" : this.getDate(), //day
			"h+" : this.getHours(), //hour
			"m+" : this.getMinutes(), //minute
			"s+" : this.getSeconds(), //second
			"q+" : Math.floor((this.getMonth()+3)/3), //quarter
			"S" : this.getMilliseconds() //millisecond
		}
		if(/(y+)/.test(format))
			format = format.replace(RegExp.$1,(this.getFullYear()+"").substr(4 - RegExp.$1.length));
		for(var k in o)
			if(new RegExp("("+ k +")").test(format))
				format = format.replace(RegExp.$1,RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
		return format;
	}
	// alert(new Date().format("yyyy-MM-dd hh:mm:ss"));
</script>
</head>

<body>
<form name="counter">
	方法A执行的开始时间:<input type="text" name="aBegin" value="" size="30"/><br/>
	方法A执行的结束时间:<input type="text" name="aEnd" value="" size="30"/><br/>
	方法A计数器:<input type="text" name="displayBoxA" value="0" size="20"/><br/>

	方法A执行的超时限制时间:<input type="text" name="expiredTime" value="2" size="30"/>秒<br/>
	方法A中用来模拟执行的死循环大小:<input type="text" name="loopSize" value="5000" size="30"/>次<br/>

	方法B执行的开始时间:<input type="text" name="bBegin" value="" size="30"/><br/>
	方法B执行的结束时间:<input type="text" name="bEnd" value="" size="30"/><br/>
	方法B计数器:<input type="text" name="displayBoxB" value="0" size="20"/><br/>
	<p> </p>
	执行测试:<input type="button" name="exe" value="开 始" onclick="methodMain();"/>  
	<input type="reset" name="tReset" value="重 置"/>
</form>
</body>
</html>
33 楼 afcn0 2007-11-12  
不是很理解hax写的,window.open我是这样测试的
a.htm
<div id="test">
</div>
<script>
setTimeout(function(){
eee=window.open("b.htm");
var temp=new Date().getTime();
for (var i=0; i<100000; i++ )
{
	if(window.t)
	{
	document.getElementById("test").innerHTML="thread2 run";
	}
	i=i+10000;
	i=i-10000;
}
document.getElementById("test").innerHTML+=new Date().getTime()-temp;

document.documentElement.appendChild(document.createTextNode("aaaaaaaaaa"));
//ie document.body.innerHTML+="aaaaaa"
},0)
</script>

b.htm
<div id="test"></div>
<script>
window.opener.document.documentElement.appendChild(document.createElement("hr"));
//ie window.opener.document.body.innerHTML+="<hr>"
</script>

经测试ff ie均表示open不用等待窗口load完毕继续执行下面代码,和XHR的异步差不多,并且open的窗口不是立即执行,而是等待主窗口js停止执行后才进行load动作,所以看到是先有aaaaa字符,后有hr的横线,open好似只是注册一个要打开的窗口,而不是立即执行,有点timeout意思
32 楼 hax 2007-11-12  
myy 写道

据我所知,IE6 (IE7标签页方式不清楚) 用 open(), _balnk, Ctrl+N 等各种方式打开的新窗口都是在独立的线程中运行的,并且同时都属于一个IE进程,"浏览器的主线程"这种说法也不确切,事实上,同一个IE进程每个IE窗口线程都是平等的,根本没有哪个是"主线程"之说。也就是说,每个IE窗口线程中都有"全套"的东西,包括 js引擎。(不过,底层的网络通讯采用了线程池,这个是共享的)。

这样,虽然"JS本身一定是单线程的",但是open()创建了两套"在不同线程中的js引擎环境",通过这样来模拟 LZ 的要求是可行的。


首先open,ctrl-n出来的窗口,与原窗口肯定同属一个进程。你用桌面图标启动的新的IE窗口就在另外一个进程里,那不在我们的讨论范围之内。其次,你说它们都在独立的窗口线程里,maybe。但我指的是主线程,就是浏览器的主控线程,其他线程都是从这个线程上分支出来的。当然,偶不清楚IE内部构造到底是如何的。但是一个IE窗口不应该有全套的东西,否则就变成一个独立的进程了。而且即使每个窗口都一个独立的js引擎,其执行也是线性化的。这很容易推理出来,因为一个窗口的脚本可以调用另一个窗口的脚本,也就是一个窗口的脚本一定可以阻塞另一个窗口的脚本。这就是我为什么说窗口对于脚本来说没有意义的原因。

测试代码:

<html>
<head>
<title>Test JS thread</title>
<script>
function heavyWork(size) {
	info('Start a heavy work...');
	size = size || 1000;
	var result = 0;
	for (var i = 0; i < size; i++) {
	for (var j = 0; j < size; j++) {
		result += Math.random();
	}
	}
	info('Done.');
}
function test() {
	window.open('test.html', '_blank', '');
	heavyWork();
}
function info(msg) {
	var now = new Date().getTime() % 100000;
	document.getElementById('info').innerHTML += '[' + now + '] ' + msg + '<br>';
}
window.onload = function () {
	info('loaded.');
	heavyWork();
}
</script>
</head>
<body>
<div id="info">
loading...<br>
</div>
<div>
	<button onclick="test()">Open a new window with a heavy work</button>
</div>
</body>
</html>
31 楼 hax 2007-11-12  
afcn0 写道
补充个测试
opera ie ff上面都没有显示thread2 run所以基本肯定js就是单线程的


养成写测试的习惯是很好的!事实胜于雄辩。
30 楼 fins 2007-11-12  
新开窗口的呢??
29 楼 afcn0 2007-11-12  
补充个测试
<div id="test">
</div>
<script>
function aaa(){
var temp=new Date().getTime();
for (var i=0;i<10000 ;i++ )
{
	if(window.t)
	{
	document.getElementById("test").innerHTML="thread2 run";
	}
	i=i+10000;
	i=i-10000;
}
document.getElementById("test").innerHTML+=new Date().getTime()-temp;
return i;
}
function bbb(){
t=1234;
}
setTimeout(aaa,5);
setTimeout(bbb,10);

</script>

opera ie ff上面都没有显示thread2 run所以基本肯定js就是单线程的
28 楼 afcn0 2007-11-12  
没有过多分析,只是思维上的猜测,window.open必须等待打开页面onload彻底执行完才返回,所以和原页面是单线程(此点有待实验证实),但是即便如此setTimeout可以注册在load事件后执行,所以应该可以实现多窗口多js并行
timeout interval应该看js解释器是如何实现的,比如ie就永远是单线程,alert都会终止timer的计时,但是其他解释器则不然,所以至少ie上面是没有多线程一说的,也许ff或其他确实可以实现多timer并行执行(没测试),但是还是那句话,ie不支持也是有其道理的,不要把web弄的太复杂了
...我一个菜鸟被楼上大哥称为大牛,烧的难受
27 楼 fins 2007-11-12  
晕 本来以为 hax把我教明白了 这一下又糊涂了

有没有官方的说法啊????

afcn0  hax jindw ....  等等各位js研究的大牛们
快出来给个正确答案啊
26 楼 myy 2007-11-12  
hax 写道
fins 写道
这些我理解了
但是 这个还是没明白


是否是新开窗口,对于JS来说没有意义。

除非是两个完全没有任何关联的浏览器会话,理论上是可以在两个独立线程中的。

顺带说一下,JS本身一定是单线程的(除了特定的引擎扩展之外),这并不妨碍浏览器的其它部分是多线程的(问题是现有的浏览器实现,往往把脚本执行放在浏览器的主线程中)。但是其它任何一种异步机制或者外部多线程,如果牵涉到脚本,最终都会归并到JS的这一个线程中。所以XHR是异步的,CSS渲染是异步的,打开一个新窗口是异步的……都不能改变JS脚本的执行顺序。


据我所知,IE6 (IE7标签页方式不清楚) 用 open(), _balnk, Ctrl+N 等各种方式打开的新窗口都是在独立的线程中运行的,并且同时都属于一个IE进程,“浏览器的主线程”这种说法也不确切,事实上,同一个IE进程每个IE窗口线程都是平等的,根本没有哪个是“主线程”之说。也就是说,每个IE窗口线程中都有“全套”的东西,包括 js引擎。(不过,底层的网络通讯采用了线程池,这个是共享的)。

这样,虽然“JS本身一定是单线程的”,但是open()创建了两套“在不同线程中的js引擎环境”,通过这样来模拟 LZ 的要求是可行的。
25 楼 fins 2007-11-12  
非常感谢
以前对这方面的了解确实太少了 现在知道了

谢谢


24 楼 hax 2007-11-12  
fins 写道
这些我理解了
但是 这个还是没明白


是否是新开窗口,对于JS来说没有意义。

除非是两个完全没有任何关联的浏览器会话,理论上是可以在两个独立线程中的。

顺带说一下,JS本身一定是单线程的(除了特定的引擎扩展之外),这并不妨碍浏览器的其它部分是多线程的(问题是现有的浏览器实现,往往把脚本执行放在浏览器的主线程中)。但是其它任何一种异步机制或者外部多线程,如果牵涉到脚本,最终都会归并到JS的这一个线程中。所以XHR是异步的,CSS渲染是异步的,打开一个新窗口是异步的……都不能改变JS脚本的执行顺序。
23 楼 hax 2007-11-12  
fins 写道
to hax
我明白你的意思了
其实你是指, 理论上我说的对
但是实际情况中 我例子中的A方法会一直占有CPU ,使得方法B根本得不到运行的机会,对吧?


我的意思是,由于JS是单线程执行的(除了某些带有扩展特性的引擎,如rhino),所以脚本其实没有可能进行真正意义上的多线程。

注意setTimeout/setInterval并非JS规范的一部分,而是浏览器提供的特性。而且它们本质上只是一个排程器,不可能中断尚未执行完成的脚本或者重入任何一个方法。否则必然会出现语义上的问题。真正多线程,必定要带有其它的原语,如锁定、同步、信号量——JS本身一样都没有。

我们可以用setTimeout来实现Executor和Queue,但是进入一个queue的任何一个任务一旦执行,就不可能被中断,只有它执行完成了,其他task才有机会执行。所以你必须手动把heavy的task分解成一系列小的task,才能模拟多线程。

未来的JS 2.0,我们仍然不会有多线程(除了引擎自己的扩展),但是我们有了yield,能以协程方式进行并行编程!
22 楼 fins 2007-11-12  
这些我理解了
但是 这个还是没明白

引用

这个我没明白
为什么新开个窗口后, 新窗口内执行的 js 和 原窗口是一个线程????

比如 原窗口内循环执行一个函数.
中途开了一个新窗口 新窗口内也是调用一个函数
难道那个窗口的函数要执行完了
原窗口的才会继续执行下去????

如果open的窗口 和原窗口是一个 script thread
那么 通过 <a href=... target='_blank' >....
打开的呢?? 也是???

21 楼 hax 2007-11-12  
fins 写道
to Hax
下面一段代码,确实是先执行的B, 而不是A执行完之后再执行的B啊


当然是先B后A,因为根据timer的设定,B在A前。

我说的意思恰恰是,B总在A前,即使B是一个heavytask超过了A的timer所设定的时间,但是由于script引擎是单线程的,A总是要等到B执行完毕后才有机会执行。
20 楼 hax 2007-11-12  
fins 写道
hax 写道
myy 写道
可以考虑用 window.open() 开新窗口实现,这个在IE下肯定是多线程的


You r wrong. They always in one script thread.



这个我没明白
为什么新开个窗口后, 新窗口内执行的 js 和 原窗口是一个线程????

比如 原窗口内循环执行一个函数.
中途开了一个新窗口 新窗口内也是调用一个函数
难道那个窗口的函数要执行完了
原窗口的才会继续执行下去????

如果open的窗口 和原窗口是一个 script thread
那么 通过 <a href=... target='_blank' >....
打开的呢?? 也是???


你可以尝试一下你所构思的测试例子,看看结果如何。
19 楼 halfmile 2007-11-10  
JavaScript 虚拟机在一个浏览器中有多个实例吗?如果没有就无法实现多进程了。何况即便可以多进程,JavaScript也没有提供权限来取消进程,如果简单的抛弃进程,那么是否会造成内存泄漏呢?

一般耗时的function,大多是罗列或者递归操作。如果是两种操作的话,可以用一些技巧模拟可取消的进程。一个方法是把function里面的状态取出来放在外面,然后套一个很短的(1ms)interval来反复执行。当一定条件满足的时候,比如完成或者超时,那clearInterval就可以了。
18 楼 fins 2007-11-10  
to hax
我明白你的意思了
其实你是指, 理论上我说的对
但是实际情况中 我例子中的A方法会一直占有CPU ,使得方法B根本得不到运行的机会,对吧?

相关推荐

    为jquery的ajax请求添加超时timeout时间的操作方法

    在上述代码中,complete回调函数会在Ajax请求完成时执行,无论成功、失败还是超时。通过检查status参数的值,我们可以判断请求是否因为超时而结束,并执行相应的处理操作。 总结以上所述,为jQuery的Ajax请求添加...

    基于JavaScript实现一定时间后去执行一个函数

    JavaScript中的`setTimeout()`函数是一个非常重要的工具,它允许开发者安排代码在特定的延迟后执行,这对于创建动态效果、异步处理、以及定时任务等场景非常有用。下面将详细讲解`setTimeout()`函数的使用方法和相关...

    JavaScript控制窗口2.pdf

    在JavaScript中,窗口对象(Window)是全局对象,提供了对浏览器窗口的各种控制,包括控制窗口的状态栏、访问窗口的历史记录以及设置超时等功能。 1. **控制窗口状态栏** 窗口状态栏通常位于浏览器窗口的底部,...

    网页中使用传统方法实现异步校验详解

    而在异步编程中,即使某个任务需要时间(如网络请求),程序也不会阻塞,而是继续执行其他任务,当异步任务完成时再通知程序处理结果。这使得用户体验更加流畅,尤其是在需要网络交互的场景下。 在网页中,我们通常...

    浅谈JavaScript超时调用和间歇调用

    超时调用的使用场景包括但不限于:动画和定时任务的实现,以及在一些复杂的事件处理中等待一段时间后再执行操作。例如,在一个表单验证的场景中,可以在用户停止输入一段时间后才开始验证,这可以通过setTimeout来...

    计时器实现

    在计算机编程中,计时器是一种非常重要的工具,它用于执行特定操作或在特定时间间隔后触发事件。计时器的实现方式多种多样,适用于不同的编程语言和应用场景。本篇文章将深入探讨计时器的基本原理、常见实现方法以及...

    解决js ajax同步请求造成浏览器假死的问题

    同步请求会在请求完成之前阻塞浏览器的主线程,而异步请求则允许浏览器在等待响应时继续执行其他任务。 同步请求造成浏览器假死的问题通常发生在执行耗时的网络请求时。在这个请求完成之前,浏览器不会渲染任何内容...

    前端项目-jquery-dotimeout.zip

    4. **轮询循环**:doTimeout支持在满足特定条件前持续执行某个函数,这在实现条件检测或者等待某个状态改变的场景下非常实用。 5. **去块优化**:与原生的setTimeout相比,doTimeout在执行延迟任务时考虑到了事件...

    封装一个Ext消息提示框,显示几秒后自动消失

    要实现自动消失的功能,我们可以使用 setTimeout 函数,该函数可以在指定的时间后执行某个函数。在本例中,我们可以使用 setTimeout 函数来关闭消息提示框。例如,我们可以在显示消息提示框时使用 setTimeout 函数,...

    Selenium 模拟浏览器动态加载页面的实现方法.pdf

    在实际应用中,可能还需要结合其他技巧,如设置User-Agent、处理验证码、模拟登录等,以适应各种复杂的网页抓取需求。记住,始终尊重网站的robots.txt文件,遵循抓取规则,以免引起不必要的麻烦。

    易语言取网页文本中的指定内容

    这个过程通常包括设置URL、请求方法、超时时间等参数,然后发送请求并接收服务器返回的响应。 在获取到HTML源代码后,接着是解析和抽取目标内容。这通常涉及对HTML的解析,易语言可能没有内置的HTML解析库,但可以...

    $.ajax()方法详解

    例如,在处理异步请求时,可以根据返回的数据类型进行不同的处理,比如获取JSON数据后在前端进行动态显示,或者更新页面的某个部分等。$.ajax()方法的灵活使用,大大简化了AJAX技术的应用,使得开发者能够更加专注于...

    前端开源库-jeefo_timeout

    在Web应用中,我们经常遇到需要等待某个操作完成,但又不能无限期等待的情况,这时就需要设定一个超时时间来确保程序的正常运行。jeefo_timeout作为jeefo框架的一个组成部分,为开发者提供了优雅地处理这种问题的...

    Asyncjsnode和浏览器异步工具

    使用 `delay` 函数可以实现延迟执行,而 `timeout` 则可以为异步操作设置超时,防止程序因为某个操作卡住。 6. **错误处理**: 在异步编程中,错误处理是关键。Async.js 提供了一个 `tryCatch` 高阶函数,可以...

    vue.js实现刷新当前页面的方法教程

    下面我们将详细介绍如何在Vue.js环境中实现刷新当前页面的方法。 **一、刷新原理** 刷新页面的基本思路是利用Vue Router的导航机制。首先创建一个空页面(例如:/user/back),当用户完成某个操作后,页面会跳转到...

    selenium中文API

    为了提高测试的灵活性,某些动作命令可以附加“并等待”后缀,如“点击并等待”,表示在执行动作之后,Selenium会等待浏览器加载新的页面,直至某个条件满足或者超时。 辅助命令主要用于检查应用程序的状态,并将...

    jquery-part2

    2. 异步请求:文档强调了AJAX请求的异步特性,意味着当Web浏览器发送AJAX请求到服务器时,它不需要等待服务器响应,而可以继续执行其他代码。这使得用户体验更加流畅,因为页面不需要重新加载即可与服务器进行交互。...

    DocumentloadingstatesasPromises

    除了简单的监听事件,我们还可以利用Promise链来实现更复杂的逻辑,比如在某个特定的加载状态之后执行特定的操作,或者在加载过程中添加超时机制。 6. **async/await** ES7引入的async/await语法可以让Promise的...

    DWR3精确推送的配制方法

    DWR (Direct Web Remoting) 是一个开源的Java库,它允许JavaScript在浏览器端与服务器端的Java对象进行直接交互,实现AJAX功能。在DWR3中,"精确推送"(也称为反向推送或服务器推送)是一种技术,允许服务器主动地将...

    前端开源库-wait-for-event.zip

    这个库特别适用于那些需要在特定事件触发后才能继续执行的场景,例如异步操作、动画完成或者用户确认等。 `wait-for-event` 库的核心功能在于它允许开发者注册一个回调函数,该函数会在指定的事件被触发时得到执行...

Global site tag (gtag.js) - Google Analytics