当前位置:网站首页>异步编程之promise,任务队列,事件循环
异步编程之promise,任务队列,事件循环
2022-08-04 05:34:00 【初夏半微凉】
异步编程
我们先来看一看同步编程思想是怎样的,就是一行一行的按顺序执行代码
function createData(){
return parseInt(Math.random()*(90-50)+50);
}
var obj = {
data:100,
tool:function(){
// 同步的设计思想
var data = createData();
this.data = data;
}
}
obj.tool();
console.log(obj.data);
再来看看异步编程思想,就是可以重新在开一个线程来执行代码
// 异步的设计思想,回调函数
function createData(callback){
callback(parseInt(Math.random()*(90-50)+50));
}
var obj = {
data:100,
tool:function(){
createData((n) => {
// n表示createData产生的数据
this.data = n;
} );
}
}
obj.tool();
console.log(obj.data);
异步函数
console.log(1);
// fn函数不可能是异步函数,但是js的底层 c/c++是有不阻塞代码的异步函数的
fn(function(){
console.log(3)
},1000); // 异步阻塞函数
console.log(5);
// 例如,计时器,数据库操作,读取文件,promise等等耗时的一般都会设计成不阻塞的线程
setTimeout(function(){
console.log(4)
},1000);
console.log(2);
// 打印结果 因为fn是异步阻塞函数,执行到这里就被阻塞了,就报错了
当我们写了两个setTimeout函数时,如果睡眠时间一样那么谁先写谁先执行,如果睡眠时间不一样,就是谁先醒谁就先执行
setTimeout(() => {
console.log(11)},2000 );
setTimeout(() => {
console.log(22)},1000 );
// 打印结果 22 , 11
promise函数
promise是一个ES5已经出现了 ES6直接给出标准
promise是一个构造函数 创建了一个数据容器
map set arr object 都是数据容器,被动产生数据 给他添加数据
promise主动产生 不用给他添加数据 而是它自己产生数据
我们先来创建一个promise对象
var p1 = new Promise()
那么这里的p1什么? p1 是一个对象
对象的功能是什么呢? 是保存数据的,比如数组保存了数据以后 用下标来取,比如普通对象保存数据,用属性名取值 ,Map也是特殊对象保存了数据 用get方法来取值,set也是特殊对象保存了数据,用遍历器来取值
p1也是一个特殊对象,它内部的数据是自己产生的,而不是从外界保存进去的,它的取值使用then方法来取
var p1 = new Promise(function(n1,n2){
var n = Math.random();
n1(n); // n1调用了,就代表p1产生了数据
} )
// p1数据容器取数据用then函数,是一个异步函数
var re = p1.then(function(data){
console.log(data,111);
return 200;
} )
console.log(222);
// 取数据就是传入回调函数来取 当上面运行完就会把值传入下面这个函数
// 当n1 调用完了之后就会触发下面这个函数的执行
re.then((data) => {
console.log(data,222)});
n1 是一个函数,n2 也是一个函数 ,函数的使用直接调用就好了
这个跟return是一样的只能产生n1或者n2的数据,如果两个都在那么谁先运行完了就停了
n1(n); 运行表示p1数据容器内部产生了数据:n,n1 调用代表触发了p1对象内部产生的数据
在业务中n1触发代表产生正常的数据,n2代表触发错误的数据
then函数的返回值,是一个新的promise对象
关于then传入的回调函数的返回值:
如果返回值是一个promise对象那么就是它
如果返回值不是一个promise对象,那么会把函数的结果包装为一个生成数据了的premise对象
promise ==> promise函数不是异步函数,非阻塞函数,then函数才是一个异步非阻塞函数
then里面第一个函数是取出正确的数据,第二个函数是取出错误的数据
用throw来抛出错误,下面进行捕获也是可以的
p1这个promise对象有两个函数可以使用then函数取值,还可以使用catch方法可以捕获错误信息
// 为什么要用catch呢?
// 这样就可以很方便接收错误数据了,有错误数据抛出却不接收就会报错
p1.then(function(data) {
console.log(data, 11);
}).catch(function(e) {
console.log(typeof e, e);
})
// 这里的catch触发必须是要么n2调用 要么throw抛出,就算是创建一个错误对象传给n1也不会触发catch的
任务的队列分类
任务指的就是js代码中的运行的代码
fn() 代表了fn任务的运行 脚本的运行也是一个任务,计时器的运行也是一个任务 promise也是一个任务
任务分为同步的任务 异步的任务
我们先来看同步任务
下面三个就是同步任务,一个一个的执行就叫同步任务
function fn(){
}
var a = new Array()
var b = fn()
异步任务,then括号里的写成fn()就是我们在调函数,写成fn就是计时器内部在调用函数
setTimeout(fn, 1000);
p1.then(fn);
console.log(123);
异步任务的队列优先级:异步宏任务先执行,然后再执行异步微任务
宏:脚本是一个宏任务
脚本运行 执行第一个宏任务:
- 先执行同步任务
- 添加新的宏任务到队列中,添加这一轮的异步微任务
- 执行异步微任务
// 先执行同步任务,在执行宏任务,然后执行宏任务里面的微任务,执行完后就可以执行下一个宏任务了
// 这里的setTimeout是宏任务,then是微任务
console.log(4);
setTimeout(() => {
console.log(1);
}, 0);
setTimeout(() => {
console.log(2);
setTimeout(() => {
console.log(6);
}, 200);
}, 0);
var p1 = new Promise(n1, n2) => {
n1(1000);
}
p1.then(() => {
console.log(3);
})
console.log(5);
// 执行结果是 4 5 3 1 2 6
还有一个题可以自己去看看
setTimeout(() => {
console.log(0);
});
new Promise(resolve => {
console.log(1);
setTimeout(() => {
resolve();
var p1 = new Promise((n1, n2) => {
n1(20)
})
p1.then(() => console.log(2));
console.log(3);
});
// promise同步但是没打印,然后直接then微任务
new Promise((n1, n2) => {
n1(20)
}).then(() => console.log(4));
}).then(() => {
console.log(5);
var p2 = new Promise((n1, n2) => {
n1(20)
})
p2.then(() => console.log(8));
setTimeout(() => console.log(6));
});
console.log(7);
// 打印结果 1 7 4 0 3 5 2 8 6
事件循环
什么是事件循环呢?
事件循环:就是任务开启后,内部执行的时候可能会有新任务
先执行第一轮宏任务 (脚本)中的代码:同步 - 微任务 - 下一轮宏任务中的代码
宏任务中:同步 - 微任务 - 下一轮排队的宏任务
下一轮排队的宏任务中 执行同步 - 执行微任务 - 遇到宏任务继续排队 - 执行下轮排队的宏任务
下一轮排队的宏任务中:执行同步 - 执行微任务 = 遇到宏任务继续排队 - 执行下一轮排队的宏任务
下一轮排队的宏任务中:执行同步 - 执行微任务 = 遇到宏任务继续排队 - 执行下一轮排队的宏任务
这样就事件循环起来了
边栏推荐
猜你喜欢

华硕飞行堡垒系列无线网经常显示“无法连接网络” || 一打开游戏就断网

目标检测中的先验框(Anchor)

Faster - RCNN principle and repetition code

杰哥带大家做一次meterpreter内网渗透模拟

Microsoft Store 微软应用商店无法连接网络,错误代码:0x80131500

益智小游戏- 算算总共多少正方形

你要悄悄学网络安全,然后惊艳所有人

基于爬行动物搜索RSA优化LSTM的时间序列预测

EfficientNet解读:神经网络的复合缩放方法(基于tf-Kersa复现代码)

Online public account article content to audio file practical gadget
随机推荐
无监督特征对齐的迁移学习理论框架
复杂格式的json转递
学好网络安全看这篇文章让你少走弯路
Memory limit should be smaller than already set memoryswap limit, update the memoryswap at the same
Database: Organize Four Practical SQL Server Scripting Functions
数据库:整理四个实用的SQLServer脚本函数
目标检测中的IoU、GIoU、DIoU与CIoU
IE8 打开速度慢的解决办法
并发概念基础:线程,死锁
SENet detailed explanation and Keras reproduction code
Detailed explanation of DenseNet and Keras reproduction code
A semi-supervised Laplace skyhawk optimization depth nuclear extreme learning machine for classification
注册表设置默认浏览器 win7,winserver 2008,winserver 2012
Computer knowledge: desktop computers should choose the brand and assembly, worthy of collection
基于Event Stream操作JSON
CMDB 腾讯云部分实现
QT QOpenGLWidget 全屏导致其他控件显示问题
Multi-threaded sequential output
网络安全行业是蓝景吗?
狗都能看懂的变化检测网络Siam-NestedUNet讲解——解决工业检测的痛点