精华内容
下载资源
问答
  • Javascript执行机制

    2021-04-06 09:36:23
    单线程也就意味着所有任务需要排队,前一个任务结束之后,才会执行下一个任务,这样所导致的问题是:如果js执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 为了解决这个问题,利用...

    javascript语言的一大特点是单线程,也就是说,同一时间只能做一件事。
    单线程也就意味着所有任务需要排队,前一个任务结束之后,才会执行下一个任务,这样所导致的问题是:如果js执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
    为了解决这个问题,利用多核cpu的计算能力,HTML5提出Web Worker标准,允许js脚本创建多个线程。因此出现了同步异步

    同步
    前一个任务结束后再执行后一个任务,程序的执行顺序与与任务的排列顺序是一致的、同步的;
    比如烧水的同步做法,我们要烧水煮饭,等水开了(十分钟之后),再去切菜,炒菜。
    异步
    你在做一件事情时,因为这件事会花费很长时间,在做这件事的同hi,你还可以去处理其他事情;
    比如做饭的异步做法,我们在烧水的同时,利用这十分钟,去切菜,炒菜。

    <script>
        console.log(1);
        //在下面这串代码中,因为定时器的处理时间要比其他时间要长,所以,计算机先处理时间慢的,最后再处理时间长的;这就是异步。
        window.setTimeout(function (){
            console.log(3);
        },2000);
        console.log(2);
    </script>
    

    在这里插入图片描述
    但是会存在一个问题,假如我们把定时器里的时间改为0。又是怎么处理的呢?

    我们再看一段代码并输出:

    <script>
        console.log(1);
        
        window.setTimeout(function (){
            console.log(3);
        },0);
        console.log(2);
    </script>
    

    在这里插入图片描述
    结果仍然是一样的,因此就要继续了解一下关于js执行机制的同步任务和异步任务

    同步任务
    同步任务都在主线程上执行,形成一个执行栈

        //执行栈
        console.log(1);
        setTimeout(fn,0);
        console.log(2);
    

    异步任务
    js的异步是通过回调函数实现的

    1、普通事件,如click、resize等

    2、资源加载,如load、error等

    3、定时器,包括setInterval、setTimeout等

    异步任务相关回调函数添加到任务队列中(也称消息队列)

    function fn(){console.log(3)}
    

    在这里插入图片描述
    在上图中,console.log和setTimeout都是属于同步任务的,但是setTimeout里面有个回调函数却是属于异步任务的;总结一下,js在处理过程中,会将队列划分成两部分,一是主线程执行栈,二是任务队列(消息队列)

    执行步骤
    1、先执行执行栈中的同步任务
    2、异步任务(也就是回调函数)放入任务队列中。
    3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

    在这里插入图片描述
    在上面我们列举了一个异步任务的情况,但当遇到多个异步任务(回调函数)的时候,又是怎么处理的呢?

    比如这么一段代码

        console.log(1);
        //异步任务
        document.onclick=fn;
        function fn(){
            console.log('click');
        }
        console.log(2);
        setTimeout(fn1,2000);
        //异步任务
        function fn1(){
            console.log(3);
        }
    

    按照之前的分析,先把任务分成同步任务和异步任务;但是异步任务在多数情况情况下不止一个,是不是所有的异步任务都要放到里面,还是说谁先放到前面,谁先放到后面。这个时候就要讲到异步进程处理。

    看下图

    在这里插入图片描述
    当遇到注册事件时,会把这段代码提交到异步进程处理中,只有点击之后才会将回调函数放到任务队列当中;
    同理,setTimeout异步任务在时间到之前也会提交到异步进程处理中,等时间到了之后就会放入任务队列当中。
    最后同步任务执行完毕后,再去读取任务队列中的异步任务;

    整个过程就是这样,因为注册事件没有点击,它会一直存在于异步进程处理之中,直到完成点击,进入任务队列,主线程执行栈会重新执行同步任务里的代码,然后发现异步任务,再进去任务队列里查看,再获取;

    所以由于主线程不断的重复获得任务、执行任务、再获得任务、再执行,所以这种机制被称为事件循环(event loop)
    在这里插入图片描述
    上图输出的结果并不唯一,如果在setTimeout时间未结束之前点击页面,那么此时就会先执行 document.οnclick=fn;
    在这里插入图片描述

    这就是js执行机制里的同步、异步、同步任务、异步任务、异步进程处理;

    展开全文
  • 前一个任务结束再执行下一个任务,是同步的,比如做饭的同步做法:等水煮开后(15分钟),再去洗菜,切菜,炒菜。 异步: 在做这事的同时,可以去处理其他事情,比如做饭的异步做法:在水煮开的同时

    JavaScript原先是单线程语言,也就是同一时间只能做一件事。
    单线程意味着,所有的任务需要排队,当前一个任务结束,才会执行下一个任务。如此导致的问题是:js执行时间过长,会造成页面渲染不连贯,及页面渲染加载阻塞的感觉。
    为解决该问题,HTML5允许脚本创建多个线程。于是,JS中就出现了同步和异步

    - 同步:
    前一个任务结束后再执行下一个任务,是同步的,比如做饭的同步做法:等水煮开后(15分钟),再去洗菜,切菜,炒菜。

    • 异步:
      在做这件事的同时,可以去处理其他事情,比如做饭的异步做法:在水煮开的同时,利用这15分钟去洗菜,切菜,炒菜。
    <script>
    console.log(111);
    setTimeout(function(){
    	console.log(333);
    },2000)
    // 先输出111 然后是222 最后是333
    // 222不会等着333过2秒后再输出
    console.log(222); 
    </script>
    

    同步任务:
    同步任务都在主线程上执行,形成一个执行栈。
    在上面的代码中,console.log(111)是同步任务,setTimeout()是同步任务,console.log(222)也是同步任务。
    异步任务:
    JS的异步是通过回调函数实现的。
    常见的异步任务:

    • 普通事件,比如:click
    • 资源加载,比如:load
    • 定时器,比如:setInterval、setTimeout

    setTimeout里的function函数就不属于同步任务,属于异步任务,会放到异步任务中的任务队列中。

    • 那么同步任务和异步任务JS是如何执行的?机制是什么?

    1.先执行同步任务;
    2.把异步任务(回调函数)放到任务队列中;
    3.当同步任务执行完毕,系统会按次序读取任务队列中的异步任务,读取到该异步任务后,再次进入同步任务中,然后再执行。
    4.先同步任务后异步任务

    展开全文
  • Js只有个主线程执行,如果说我们能把复杂的需要时间处理的任务,交给个模块去处理,不占用主线程,等它处理结束后,得到响应就好了举个例子:我们要做吃饭、洗衣服、和看直播这三件事这三件事就会放入我们...

    ~为什么需要异步操作?

    比起同一时间只能干一件事,我们总是追求更高的效率,一边吃饭一遍写代码还能看直播。

    比如说当我们请求一个接口,后台响应的时间非常长,如果没有异步操作,程序只能傻等,进行不了下一步操作。

    Js只有一个主线程执行,如果说我们能把复杂的需要时间处理的任务,交给一个模块去处理,不占用主线程,等它处理结束后,再得到响应就好了

    举个例子:我们要做吃饭、洗衣服、和看直播这三件事

    这三件事就会放入我们的任务队列中,如果以同步的思想来看的话,我们只能先吃饭再洗衣服,后看直播。这很傻,意味着我们做一件事情时不能做其他的。

    我们可以看直播,把衣服交给洗衣机,做饭交给电饭煲。等他们做好后滴的一声提示我,去晾衣服,和吃饭。

    需要注意的是,衣服可以交给洗衣机,就像等待服务器响应一样我可以做其他的东西。但是最后晾衣服完成洗衣服的动作,任然是需要主线程处理的。

    ~当主线程中的同步代码代码执行时间十分长

    		function a(){
    			console.log(1)
    		}
    		function b(){
    			console.log(2)
    		}
    		a()
    		b()

    ea374028d5b8c95df1883747a585ffa3.png
    这是十分理想的状态,主线程依次执行a和b,以为计算量不大执行时间都不长没有影响到b。
    		function a(){
    			for(let i=0;i<1000000000;i++){
    				if(i==999900000){
    					console.log(i)
    				}
    			}
    		}
    		function b(){
    			console.log(2)
    		}
    		a()
    		b()

    76d1fdaeb01c43e6983b07453e490b3c.png
    b在队列中等待,直到a执行完成,当a执行时间很长,这种等待有时是无法忍受的,这时我们需要异步操作
    		function a(){
    			setTimeout(()=>{
    				for(let i=0;i<1000000000;i++){
    					if(i==999900000){
    						console.log(i)
    					}
    				}
    			},0)
    		}
    		function b(){
    			console.log(2)
    		}
    		a()
    		b()

    52caaf7d93ba5c7532b8a5435b534476.png
    将a转为异步时,只有b在主线程,他会立刻执行

    ~eg:异步加载图片

    		function loadImg(url,resolve,reject){
    			let img = new Image()
    			console.dir(img)
    			img.src=url
    			img.onload=()=>{
    				resolve(img)
    			}
    			img.onerror=reject
    		}
    
    		loadImg('https://i1.hdslb.com/bfs/face/a3d75e10c363fccfe994b708ddb19caa2e6e1c5e.jpg@52w_52h.webp',
    			(img)=>{
    				document.body.appendChild(img)
    				console.log('resolve')
    			},
    			()=>{
    				console.log('reject')
    			},
    		)
                   console.log(123)

    处理图片的时间显然很长,Js将其转为异步执行,这其中可能执行成功可能失败,我们用回调接收响应。就上文所说,做饭交给电饭煲,做好了通知我去吃,做糊了我去重做,期间我们可以去做的别的事情,就像下面执行的同步代码输出123。

    ~当两个异步操作同时触发,如何控制先后

    		function js(url,call){
    			let script=document.createElement('script')
    			script.src=url
    			document.body.appendChild(script)
    			script.onload=call
    		}
    
    			js('one.js',()=>{
    				one()
    			})
    			js('two.js',()=>{
    				two()
    			})
    

    77b082adf6e9658dd336a3756d12c211.png

    08f2c7000d665c006dc0d49c7f9a563e.png
    js异步加载了两个js文件,但因为他们都是异步的,无法控制先后

    如果想让two在one.js加载后再加载,最简单的方法就是,在one的回调中,加载two

    		js('one.js',()=>{
    			one()
    			js('two.js',()=>{
    				two()
    			})
    		})

    但是这样有一个问题,当业务逻辑非常复杂时,不停的在嵌套,出现回调地狱有两个问题,第一是代码非常不美观冗余,第二当在多层嵌套中,有一层出现了问题,我们无法处理捕获错误,只能在其中判断,造成代码更加冗余。

    4f4a528fc9d1daca4c2fc1623496ae9e.png

    Promise

    ~用来做什么?

    从上面的内容我们可以了解到,书写代码中回遇到代码嵌套造成的回调地狱,以及代码执行中的错误捕获,还有异步代码执行时的先后顺序,Promise 这个Es6中新加入的内容,就是用来解决这一系列的问题。

    ~Promise 的基本用法

    ~~创建promise对象

    new Promise((resolve,rejeck)=>{
    
    })  //构造函数创建一个新的 Promise对象
    

    ~~promise状态

    promise有两个参数,resolve和reject,分别对应成功响应与失败响应,当没有抛出失败或成功是,这个promise对象就在pending等待状态

    console.log(new Promise((res,rej)=>{}))

    c2819547c9afdb5b4df0e9ef52e411c5.png
    等待状态
    console.log(new Promise((res,rej)=>{res(1)}))

    98ab45e0f9edb6a477c87dd4b90adcb9.png
    成功状态
    console.log(new Promise((res,rej)=>{rej(1)}))

    1a8c9afc7d28122e71752bae697c48f1.png
    失败状态

    ~~成功与错误捕获

    当Promise对象状态发生改变,就由then或catch捕获

    new Promise((res,rej)=>{
       res('成功')
    })
    .then((res)=>{
       console.log(res)  //'成功' then第一个参数捕获成功
    })
    
    new Promise((res,rej)=>{
       rej('失败')
    })
    .then((res)=>{
       console.log(res)  
    })
    .catch((error)=>{
       console.log(error)  //'失败' 利用catch捕获失败
    })
    
    new Promise((res,rej)=>{
       rej('失败')
    })
    .then((res)=>{
       console.log(res)  
    },error=>{
       console.log(error)   //'失败' 利用then第二个参数捕获失败
    })

    ~~then()执行顺序

    上面提到then中的代码时等待promise对象做出响应后才开始执行,表明它不是同步代码,事实也确实如此,then放在微任务队列等待执行,等待本轮主线程执行完毕后执行。具体可以看之前的 工作笔记 JS任务机制

    ~~then的链式调用

    then中的代码都是微任务,在微任务队列中他们也按照顺序执行,可以理解为某种的同步,

    two		new Promise((res)=>{
    			res(1)
    		})
    		.then((res)=>{
    			console.log('one')
    		})
    		.then(()=>{
    			console.log('two')
    		})
    
    //先输出one后输出two
    
    		new Promise((res)=>{
    			res(1)
    		})
    		.then((res)=>{
    			for(let i=0;i<9999;i++){
    				for(let x=0;i<9999;x++){
    					console.log(1)
    				}
    			}
    		})
    		.then(()=>{
    			console.log('two')
    		})
    
    //先输出1后输出two
    
    		new Promise((res)=>{
    			res(1)
    		})
    		.then((res)=>{
    			setTimeout(()=>{
    				console.log(1)
    			},0)
    		})
    		.then(()=>{
    			console.log('two')
    		})
    //先输出two后输出1

    ~~Promise链式调用

    		let promise=new Promise((res,rej)=>{
    			res('成功')
    		})
    		new Promise((res)=>{
    			res(promise)
    		})
    		.then((res)=>{
    			console.log(res) //'成功'
    		})

    Promise改变状态是其他Promise时,执行then时需要等待父级的响应

    		let promise=new Promise((res,rej)=>{
    			setTimeout(()=>{
    				console.log(1)
    			},0)
    			res('成功')
    		})
    		new Promise((res)=>{
    			console.log(2)
    			res(promise)
    		})
    		.then((res)=>{
    			console.log(res)
    		})
    
    // 2 成功 1
    2是同步代码
    成功是微任务
    1是宏任务
    输出的then的成功,需要父级promise的响应

    ~~Promise状态不可逆

    在promise中执行到一个状态后,then的代码已经放在微任务队列中了,这个promise对象的状态永久的改变了并且无法改变。

    32b9546dffc802d351d09e579cf73db2.png
    不会走失败

    ~~每个then都是一个Promise

    52a3e792db6c2947e6d527aaaae5ad48.png
    打印出来的p2也是一个promise

    c795cd130ebb9b90562b6e2cfcc9a3a7.png
    状态的改变,注意任务执行顺序,这里就不强调了

    6947df0d5ceff932df2551eab026cd56.png
    为新的then传递参数

    49748945bc0776c1161066c8ee3ecc66.png

    ~~Prmise自己的then和链式的then哪个先触发?

    一句话里面的then就是外面then的处理,并会被外面捕获

    70c39c5f57e46d444f03a903ee2ec9bf.png
    我们上面说过每一个then返回的都是一个新的Promise,哪么p2有两个then,一个是自己retrun出去的then,一个是外面链式调用的then,哪么会先执行哪个呢?

    b3761dfdcd540f2344e1688f9f83a201.png
    自己的then先触发,return出去的数据外面的then捕获

    ~~Promise任务队列

    所谓任务队列就是一个个排序,依次执行。通过上面的学习,我们可以通过then来进行队列执行。但需要注意的是,每个then都需要返回一个Promise而且它的状态需要改变

    6f72ae0ad390f3df23f33c3cd65c8b69.png

    4a06239707771c467be9d2984e989dc6.png
    间隔一秒后输出

    通过上面的学习,我们可以改写为这样

    61b2dd37680be0e68c427ce98d02b13b.png
    注意promise=promise.then()是赋值语句,等待右侧的执行结果,可以想象为5个then链式调用在一起

    如果我们请求两个彼此依赖接口实现队列,我们可以这样写

    		function p(arr){
    			let promise=Promise.resolve()
    			arr.map(item=>{
    				promise=promise.then(()=>{
    					return item()
    				})
    			})
    		}
    		function p1(){
    			return new Promise(res=>{
    				setTimeout(()=>{
    					res()
    					console.log(1)
    				},1000)
    			})
    		}
    		function p2(){
    			return new Promise(res=>{
    				setTimeout(()=>{
    					res()
    					console.log(2)
    				},1000)
    			})
    		}
    		p([p1,p2])

    35d359e1f6078a92234cabd96b93cb3e.png
    循环的时候then必须返回一个Promise并且状态改变,这一点需要记住

    换成reduce更简洁一些

    		function p(arr){
    			arr.reduce((promise,item)=>{
    				return promise.then(res=>{
    					return item()
    				})
    			},Promise.resolve())
    		}
    		function p1(){
    			return new Promise(res=>{
    				setTimeout(()=>{
    					console.log(1)
    					res()
    				},1000)
    			})
    		}
    		function p2(){
    			return new Promise(res=>{
    				setTimeout(()=>{
    					console.log(2)
    					res()
    				},1000)
    			})
    		}
    		p([p1,p2])

    模拟工作环境

    ae01806823b915d8f9453d043f232f6f.png

    13a6c81df6b13e1f45b2ffed22c61802.png

    14db32a1a28f76e8a721273c9bddb4a4.png
    队列请求,这是不用then链式调用和async的解决办法

    ~~catch() 与 then()捕获错误的区别

    一句话处理自身的Promise的用then第二个参数,链式调用底部用catch兜底

    ~~finally()

    不论Promise成功还是失败都会执行finally,和then相同在Promise后面调用.

    应用场景如请求一个接口,不论成功失败最后都要取消掉loding动画我们就可以放在finally里

    ~~Promise封装异步加载图片

    上文我们用回调函数创建了的加载图片,我们学习了Promise可以改造一下

    		function image(url){
    			return new Promise((res,rej)=>{
    				let img=new Image()
    				img.src=url
    				img.onload=()=>{
    					res(img)
    				}
    				img.onerror=rej
    				document.body.appendChild(img)
    			})
    		}
    		image('https://i2.hdslb.com/bfs/face/7e998fc9ba59e2e79a39bfdb620b5cdbb7ea04e3.png@86w_86h.webp').then(
    			(res)=>{
    				let img=res
    				img.style.border='10px solid red'
    			}
    		)

    ~~Promise封装定时器

    		function timeOut(time=1000){
    			return new Promise((res,rej)=>setTimeout(()=>{res()},time))
    		}
    		timeOut(2000).then(
    			()=>{
    				console.log(123)
    				return timeOut(1000)
    			}
    		)
    		.then(()=>{
    			console.log(456)
    		})

    ~~使用Promise异步改变样式

    	        .div{
    			width: 200px;
    			height: 200px;
    			background: red;
    			position: absolute;
    		}	
    
    
                    let div=document.querySelector('.div')
    		function interval(time=10,call){
    			return new Promise((res)=>{
    				let id=setInterval(()=>{
    					call(id,res)
    				},time)
    			})
    		}
    		interval(50,(id,res)=>{
    			let left=parseInt(window.getComputedStyle(div).left)
    			div.style.left=left + 10 + 'px'
    			if(left>=300){
    				clearInterval(id)
    				res(div)
    			}
    		})
    		.then((div)=>{
    			return interval(50,(id,res)=>{
    				let width=parseInt(window.getComputedStyle(div).width)
    				div.style.width=width - 10 + 'px'
    				if(width<30){
    					clearInterval(id)
    					res(div)
    				}
    			})
    		})
    		.then((res)=>{
    			div.style.background='#333'
    		})

    尝试一下不使用Promise而是使用回调函数多层嵌套,回变成什么样子

    ~~all()

    等待多个异步执行,后返回结果。最常用的场景app下来刷新,可能要重新请求多个接口,都这些异步接口都请求完毕后,结束lodding动画

    		let p1=new Promise((res,rej)=>{
    			setTimeout(()=>{
    				res(1)
    			},1000)
    		})
    		let p2=new Promise((res)=>{
    			setTimeout(()=>{
    				res(2)
    			},2000)
    		})
    		let all=Promise.all([p1,p2])
    		all.then(
    			(res)=>{
    				console.log(res,11)
    			}
    		)

    80d4f6dc92282165eff25def73af486b.png
    在等待了两秒中后返回,res是promise数组的成功回调

    all捕获错误

    f292cbc5ecc36a4e3e18d8995eb13d85.png
    		let p1=new Promise((res,rej)=>{
    			setTimeout(()=>{
    				rej(1) //err
    			},1000)
    		})
    		let p2=new Promise((res)=>{
    			setTimeout(()=>{
    				res(2)
    			},2000)
    		})
    		let all=Promise.all([p1,p2])
    		all.then(
    			(res)=>{
    				console.log(res,11)
    			}
    			,
    			(err)=>{
    				console.log(err,22)
    			}
    		)

    f292cbc5ecc36a4e3e18d8995eb13d85.png
    我们依然可以捕获错误

    ~~allSettled()

    与all的区别是,all捕获到一个错误,就会被捕捉,而且成功的也不会被resolve捕捉,就像是一个Promise一样状态被永远不可逆改变为失败状态一样。而allSettled则是不管是否有错误,都会走resolve不会被catch捕捉,在resolve中显示成功失败的数组。

    		let p1=new Promise((res,rej)=>{
    			setTimeout(()=>{
    				rej(1) //err
    			},1000)
    		})
    		let p2=new Promise((res)=>{
    			setTimeout(()=>{
    				res(2)
    			},2000)
    		})
    		let all=Promise.allSettled([p1,p2])
    		all.then(
    			(res)=>{
    				console.log(res,11)
    			}
    			,
    			(err)=>{
    				console.log(err,22)
    			}
    		)

    6ee355fc925dc6b54906f7a7067949b5.png
    返回promise的状态和返回值

    ~~race()

    race和他的翻译一样赛马,放入多个Promsie,最先执行的完成的返回,成功res失败被catch捕捉

    		let p1=new Promise((res,rej)=>{
    			setTimeout(()=>{
    				rej(1) //err
    			},1000)
    		})
    		let p2=new Promise((res)=>{
    			setTimeout(()=>{
    				res(2)
    			},2000)
    		})
    		let all=Promise.race([p1,p2])
    		all.then(
    			(res)=>{
    				console.log(res,11)
    			}
    			,
    			(err)=>{
    				console.log(err,22) //1 22
    			}
    		)

    async/await

    async/await是Es2017加入的是Prmise的语法糖

    ~~async

    在函数前使用,将函数返回为一个Prmise

    		async function p1(){
    			return 1
    		}
    		console.log(p1())
    		p1()
    		.then((res)=>{
    			console.log(res) 
    		})

    76579c4cfb6effade9db21712826f865.png
    我们可以看到返回出来一个Promise
    		let p1 =new Promise((res)=>{
    			res(1)
    		}) 
    		console.log(p1)

    3be1ea1640096b8dca86a032776edd28.png
    从上面我可以看到async就是Promise的语法糖

    ~~await

    await等待Promise返回结果

    简单的来说 await就是用替代then链式调用的。是得可以更加优雅的书写

    如果有多个异步操作需要排列执行,await配合async就非常适合

    		async function p(){
    			await time()
    			await time(3000)
    			await time(2000)
    		}
    		function time(Time=4000){
    			return new Promise(res=>{
    				setTimeout(()=>{
    					res(Time)
    					console.log(Time)
    				},Time)
    			})
    		}	
    		p()

    15c288bdc64f3fceeb9a4169fba8e4f3.png
    4s 2s 3s

    ~~async/awite的错误机制

    当多个awite在执行是,有一个执行错误,后续的awite将不再执行

    		async function p(){
    			let p1=await time()
    			console.log(p1)
    			let p2=await time(2000)
    			console.log(p2)
    			let p3=await time(3000)
    			console.log(p3)
    		}
    		function time(Time=1000){
    			return new Promise((res,rej)=>{
    				setTimeout(()=>{
    					if(Time==2000){
    						rej('err')
    					}
    					res(Time)
    				},Time)
    			})
    		}	
    		p()

    fbf3c02b56f66d8a2862a30cee2af37c.png

    这是很常见的情况,请求三个接口,每个都彼此依赖,一个出现错误,下面的都执行不下去。通过上文我们可以很好的用then和catch的捕获机制处理。而用async/awite时我们依然可以捕获

    94d8ddabca7729b6a331e0e032b3b7e0.png

    ca25feb3894acc94268c785c09a734be.png

    297ad278f185a24de217a8f6a08ccaba.png
    或者是这样
    展开全文
  • 加入了 输出执行SQL 和 执行时间 到日志的功能。对应的方法“是否输出SQL”和“置是否输出SQL”。可随时开启和关闭(线程安全)。 [网站服务器] 加入了 等待结束 方法。等待服务器运行直到停止或者结束...
  • 同步与异步

    2016-09-21 16:47:02
    “单线程”:指一次只能完成一件任务,一个任务完成之后再执行下一个任务。 同步:即阻塞模式。必须完成一件任务再进入下一个任务。 由于js是单线程的,为了解决浏览器因为执行一个任务时间太久或者无响应,js...

    javascript语言的执行环境是“单线程”。

    “单线程”:指一次只能完成一件任务,一个任务完成之后再执行下一个任务。

    同步:即阻塞模式。必须完成一件任务再进入下一个任务。


    由于js是单线程的,为了解决浏览器因为执行一个任务时间太久或者无响应,js语言将执行模式分成2种:同步和异步

    异步:即非阻塞模式。一个任务有一个或者多个回调函数,前一个任务结束后不是执行后一个任务,而是执行回调函数。后一个任务不等前一个任务结束就执行。

    所以耗时很长的操作都要选择异步模式,避免浏览器失去响应。


    异步模式有4种,最熟悉的是ajax操作请求,回调函数。

    同步和异步的详细解说可以参考http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html


    展开全文
  • JS

    2021-02-02 18:00:10
    为了解决这个问题(单线程,一步执行完再执行下一步),利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是JS中出现了同步和异步。 同步 前个任务结束后再执行后个任务,...
  • 并发强调的时在同一个时间段内同时执行多个任务,所以在单cpu的时候会根据时间片来进行执行执行完一个时间片之后切换到下一个进程的时间去进行执行,以此来觉得是同时执行,而实际上每个cpu只会干一件事。...
  • 意味着一件事结束以后 才能进行下一件事。 HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是有了同步和异步。 同步: 前一个任务结束再执行后一个任务,程序执行顺序与任务的排列顺序是一致的、...
  • this指向问题 ...同步:前一个任务结束再执行后一个任务,程序的执行顺序和任务的排列顺序是一致的、同步的; 异步:做一件事情会花费较长时间,做这件事情的同时,可以去处理其他的事情; console.lo
  • 在许多人的无私奉献以及这种语言本身的源代码自由性质,它演变成为种特点丰富的语言,而且现在还在成长中。 PHP虽然很容易学习,但是速度上比mod_perl(植入web服务器的perl模块)慢。现在有了可以与mod_perl...
  • JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。如果排队...
  •  真正全力开始这本书的写作与组稿,是在2009年3月结束一个客户为期8天的定制培训之后,客户的DBA们强烈建议我组织本DBA工作实践的书,不一定要多深奥,但要可以给想要或者刚刚进入这个行业的DBA们一些参考,让...
  • C#微软培训资料

    2014-01-22 14:10:17
    <<page 1>> page begin==================== 目 目目 目 录 录录 ...第部分 C#语言概述.4 ...第章 ...第章第章 ...第章 .NET 编 ... 1.1 Microsoft.NET——场新的革命.4 ...这天 微软公司正式推出了其一代...
  • C#数据结构

    2013-12-10 11:49:54
    1、有穷性(Finity):个算法总是在执行有穷步之后结束,即算法的执行时间是 有限的。 2、确定性(Unambiguousness):算法的每个步骤都必须有确切的含义,即无二 义,并且对于相同的输入只能有相同的输出。 3、输入...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    C#--微软.NET的第语言 本书着重介绍语言本身,比较少涉及应用,不错的入门书,从头讲起,不怕不明白。 <<page 1>> page begin==================== 目 目目 目 录 录录 录 第部分 C#语言概述.4 ...
  • 新版Android开发教程.rar

    千次下载 热门讨论 2010-12-14 15:49:11
    Android 是个专门针对移动设备的软件集,它包括个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...
  • 岳维功 ortp-realease.pdf

    2020-12-24 04:00:17
    调度询问当前会话是否可以进行发送和接收,如果不能进行收发操作,则处理下一个会话。 这有点类似接口上的操作。调度模块使用的数据结构主要为 ,如下图 所示: Reschedule list all sessions r sessions r max w ...
  • .Linux的网络服务.......................................................................................................24 二.几种重要的配置文件......................................................
  • 同一个时间只能做一件事。根据 <a href="https://www.w3.org/TR/html5/webappapis.html#event-loops">HTML 规范</a>: <p>To coordinate events, user interaction, scripts, rendering, networking, and so ...
  • 指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。 语法:goto label(label是参数,指定所要转向的批处理程序中的行。) Sample: if {%1}=={} goto noparms if {%2}=={} goto noparms(如果这里的if...
  • 9.这时再执行程序,输入用户名为qt,密码为123456,按登录按钮便能进入主 窗口了,如果输入错了,就会弹出警告对话框。 如果输入错误,便会弹出警告提示框: 10.在logindlg.cpp 的loginDlg 类构造函数里,添上初始化...
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    -F:这个命令通常和-a一起使用,它会为每个mount的动作产生个行程负责执行。在系统需要挂上大量NFS文件系统时可以加快加载的速度。 -f:通常用于除错。它会使mount不执行实际挂上的动作,而是模拟整个挂上的...
  • ②本进程结束负责通知下一进程;③进程调度,不能阻塞。 (3)原语 原语是不可中断的过程。 •加锁/开锁(LOCK/UNLOCK)原语 优点是实现互斥简单;缺点是效率很低。 •信号量(Semaphore)及PV...
  • 代码语法错误分析工具pclint8.0

    热门讨论 2010-06-29 07:00:09
    和前面第步中的方法基本一样,不过这里我们需要用到unix中的find等命令来查找当前目录的C和C++文件,然后将它们送给lint程序处理,所以得先从http://www.weihenstephan.de/~syring/win32/UnxUtils.zip下载...
  • LECCO SQL Expert (智能自动SQL优化)

    热门讨论 2006-01-13 09:51:35
    但是要想熟练使用SQL语句,也不是一件简单的事,有些语句使用起来也比较麻烦。如果我们对SQL语句进行优化,那么用户使用起来 就会方便许多。 简单来说,SQL语句的优化就是将性能低下的SQL语句转换成达到同样目的的...

空空如也

空空如也

1 2 3 4 5 6
收藏数 102
精华内容 40
关键字:

时间结束再执行下一件