JS中的同步和异步机制

概念

同步: 在一个线程上(主栈/主任务队列)同一个时间只能做一件事情,当前事情完成后才能进行下一个事情(先把一个任务进栈执行,执行完成,再把下一个任务进栈,上一个任务出栈)

异步:在主栈中执行一个任务,但是发现这个任务是一个异步的操作,会把它移除主栈,放到等待任务队列中(此时浏览器会分配其他线程监听异步任务是否到达指定的执行时间),如果主栈执行完成,监听者会把到达时间的异步任务重新放到主栈中执行…

常见异步:

[宏任务: macro task]

  • 定时器
  • 事件绑定
  • ajax
  • 回调函数

[微任务:micro task]

  • Promise(async/await)
  • process.nextTick
  • Node中的fs可以进行异步的I/O操作
    执行顺序 SYNC -> micro -> macro
setTimeout

//1
setTimeout(() => {
  console.log(1);
}, 20);
//2
setTimeout(() => {
  console.log(2);
}, 0);

console.time('W');
let i = 0;
while(i < 99999999){
  i++;
}
console.timeEnd('W');
setTimeout(() => {
	//3
  console.log(3);
}, 10);
//4
console.log(4)

执行过程:
程序自上而下执行,将前两个异步任务放进等待队列,然后进入while循环,执行了500多ms,此时前两个异步任务已经到达时间,而且2在1前,(注意setTimeout里的时间为最小等待时间)。之后把3加入等待任务队列,遇到4输出。
最后输出4 2 1 3

因此更加能够体会到:setTimeout里面的时间,其实是将函数放入等待队列的时候开始计算的。
如果将99999999变为10呢?那毫无疑问,应该是4 3 2 1

Ajax
let xhr = new XMLHttpRequest();
xhr.open('get', 'xxx.txt');
xhr.send();
/*放等待任务队列之前状态是1*/
xhr.onreadystatechange = () => {
	console.log(xhr.readyState);
} 
/*主栈空闲了*/
//状态为2 执行函数
//状态为3 执行函数
//状态为4 执行函数
Promise
console.log(1);
//Promise本身的Excutor为同步执行
new Promise((resolve, reject) => {
	console.log(2);
	setTimeout(() => {
		resolve()//Promise内部机制:执行resolve会把之前基于then存放的方法执行
	}, 10);
}).then(() => {console.log(3)});
console.log(4);
//1 2 4 3
async / await
function AA() {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			Math.random() < 0.5 ? reject(100): resolve(200);
		})
	})
}

async function fn() {
	console.log(2);
	let res = await AA();
	/* 
	 * 1.先把AA执行,返回一个Promise实例
	 * 2.它会暂时跳出当前正在执行的函数,将后面的代码放到等待队列
	 * 3.主栈暂时空闲
	 * 4.当主栈的其他任务完成,并且AA中的Promise也已经计算完成最后的结果,再把之前的第二步放到等待队列的内容,拿回主栈执行
	 */
	console.log(3);
}
fn();
console.log(4);
async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}
console.log('script start');
setTimeout(function() {
  console.log('setTimeout');
}, 0);
async1();
new Promise(function(resolve){
  console.log('resolve1');
  resolve();
}).then(function() {
  console.log('promise2');
})
console.log('script end');
//script start  
//async1 start 
//async2
//resolve1 
//script end 
//promise2
//setTimeout

process

//=>process.nextTick
process.nextTick(()=>{})
//把当前任务放到主栈最后执行
//当主栈执行完,先执行nextTick

//=>process.env.NODE_ENV:全局环境变量
//用途:区分不同环境的不同操作,开发环境、测试环境、生产环境。
let ENV = process.env.NODE_ENV;
if(ENV === 'dev'){
	console.log('我是开发环境');
}
if(ENV === 'pro') {
	console.log('我是生产环境');
}
if(ENV === 'test'){
	console.log('我是测试环境');
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值