Promise对象
-
Promise是一个构造函数 创建了一个数据容器
-
Promise主动产生数据 不用给它添加数据 而是它自己产生数据
1.创建Promise对象(new方法)
- resolve:异步操作执行成功后的回调函数
- reject:异步操作执行失败后的回调函数
var p = new Promise(function(resolve, reject){
})
2.取出Promise对象中的数据
运行一次业务只能产生一个数据,只能是正确数据或者错误数据
2.1 then方法(取出正确的业务数据)
-
then函数是一个异步函数
-
then函数的返回值是一个新的promise对象
-
then传入的回调函数的返回值:
1.如果是一个promise对象 那么就是它
2.如果不是一个promise对象,那么就会把函数的结果包装为一个生成数据了的promise对象
var p1=new Promise(function (n1,n2) {
n1(100)//触发 让Promise对象内部产生正确的数据
});
var re=p1.then(function(el){
console.log(el,111)
return 200
})
console.log(re);
分析:n1()函数与then函数传入的函数不是同一个函数,n1函数时promise对象内置的一个产生正确数据的函数,then函数会将n1函数产生的正确的数据传给function。
2.2 catch()方法,捕获错误信息
var p1 = new Promise(function(n1, n2) {
var data = {
code: 404,
info: "假数据 代表以后写业务 生成的数据 比如网络请求"
}
if (data.code == 404) {
n2(data.info) //触发 告知Promise体系 经过1s后产生了数据,但是是n2触发说明是业务错误的数据
} else if (data.code == 200) {
var err=new Error("正确的业务对象 但是它是个js中的err类型的对象")
n1(err)
}
})
p1.then((re) => {
console.log(re, 333)
})
.catch((err) => {
console.log(err, 22)
})
任务队列和事件循环
同步任务:按先后顺序执行 function fn(){};var a=new Array();var b=fn()
异步任务:可以和其他任务同时进行 setTimeout(fn,1000);p1.then(fn)
异步任务的队列优先级: 异步宏任务先执行 然后在执行异步微任务
宏:脚本就是一个宏任务
事件循环任务开启后,内部执行的时候可能会有新的任务
脚本运行,执行第一个宏任务
1. 先执行同步任务
2.添加新的宏任务到队列中 添加新的的异步微任务
3.执行异步微任务
案列:
<script>
console.log(4)
setTimeout(() => {
setTimeout(()=>{console.log(6)},0)
console.log(1)
var p2 = new Promise((n1, n2) => {
n1(1000)
})
p2.then(()=>{console.log(7)})
}, 0)
setTimeout(() => {
setTimeout(() => {console.log(2)}, 200)
var p3 = new Promise((n1, n2) => {
n1(1000)
})
p3.then(()=>{console.log(8)})
console.log(2)
}, 0)
var p1 = new Promise((n1, n2) => {
n1(1000)
})
p1.then(() => {console.log(3)})
console.log(5)
</script>
分析:
1.脚本运行,执行宏任务
<script>
console.log(4)
setTimeout(() => {
setTimeout(()=>{console.log(6)},0)
console.log(1)
var p2 = new Promise((n1, n2) => {
n1(1000)
})
p2.then(()=>{console.log(7)})
}, 0)
setTimeout(() => {
setTimeout(() => {console.log(2)}, 200)
var p3 = new Promise((n1, n2) => {
n1(1000)
})
p3.then(()=>{console.log(8)})
console.log(2)
}, 0)
var p1 = new Promise((n1, n2) => {
n1(1000)
})
p1.then(() => {console.log(3)})
console.log(5)
</script>
2.先执行同步任务,
console.log(4),console.log(5),打印4,5
var p1 = new Promise((n1, n2) => {
n1(1000)
})
3.添加新的异步宏任务到下一循环
setTimeout(() => {
setTimeout(()=>{console.log(6)},0)
console.log(1)
var p2 = new Promise((n1, n2) => {
n1(1000)
})
p2.then(()=>{console.log(7)})
}, 0)
setTimeout(() => {
setTimeout(() => {console.log(2)}, 200)
var p3 = new Promise((n1, n2) => {
n1(1000)
})
p3.then(()=>{console.log(8)})
console.log(2)
}, 0)
添加新的的异步微任务:
p1.then(() => {console.log(3)})
4.执行异步微任务
p1.then(() => {console.log(3)}),打印3
5.执行异步宏任务
setTimeout(() => {
setTimeout(()=>{console.log(6)},0)
console.log(1)
var p2 = new Promise((n1, n2) => {
n1(1000)
})
p2.then(()=>{console.log(7)})
}, 0)
5.1.执行同步任务
console.log(1),打印1
var p2 = new Promise((n1, n2) => {
n1(1000)
})
5.2.添加异步宏任务
setTimeout(()=>{console.log(6)},0)
添加异步微任务
p2.then(()=>{console.log(7)})
5.3.执行异步微任务
p2.then(()=>{console.log(7)}),打印7
6.执行异步宏任务
setTimeout(() => {
setTimeout(() => {console.log(2)}, 200)
var p3 = new Promise((n1, n2) => {
n1(1000)
})
p3.then(()=>{console.log(8)})
console.log(2)
}, 0)
6.1 执行同步任务
console.log(2),打印2
var p3 = new Promise((n1, n2) => {
n1(1000)
})
6.2 添加异步宏任务
setTimeout(() => {console.log(2)}, 200)
添加异步微任务
p3.then(()=>{console.log(8)})
6.3 执行异步微任务
p3.then(()=>{console.log(8)}),打印8
7.执行异步宏任务
setTimeout(()=>{console.log(6)},0)
7.1执行同步任务
console.log(6)},打印6
8.执行异步宏任务
setTimeout(() => {console.log(2)}, 200)
8.1执行同步任务
console.log(2)},打印2
9.因此打印 453172862
Promise笔试题
<script>
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);
setTimeout(()=>{console.log(9)},0)
});
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);
</script>
分析:
1.执行宏任务:
<script>
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);
setTimeout(()=>{console.log(9)},0)
});
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);
</script>
2.执行同步任务
new Promise(resolve => {
console.log(1);打印1
setTimeout(() => {
resolve();
var p1=new Promise((n1,n2)=>{n1(20)})
p1.then(() => console.log(2));
console.log(3);
setTimeout(()=>{console.log(9)},0)
});
console.log(7);打印7
打印 1 7
3.添加异步宏任务
setTimeout(() => {
console.log(0);
});
setTimeout(() => {
resolve();
var p1=new Promise((n1,n2)=>{n1(20)})
p1.then(() => console.log(2));
console.log(3);
setTimeout(()=>{console.log(9)},0)
}
添加异步微任务
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));
});//当resolve()函数执行时才能执行
4.执行异步微任务
new Promise((n1,n2)=>{n1(20)}).then(() => console.log(4));打印4
打印 4
5.执行异步宏任务
setTimeout(() => {
console.log(0);
});
5.1执行同步任务
console.log(0);打印0
打印 0
6.执行异步宏任务
setTimeout(() => {
resolve();
var p1=new Promise((n1,n2)=>{n1(20)})
p1.then(() => console.log(2));
console.log(3);
setTimeout(()=>{console.log(9)},0)
}
6.1执行同步任务
resolve();
var p1=new Promise((n1,n2)=>{n1(20)})
console.log(3);打印3
打印 3
6.2 因为resolve()执行,上一轮的异步微任务
.then(() => {
console.log(5);
var p2=new Promise((n1,n2)=>{n1(20)})
p2.then(() => console.log(8));
setTimeout(() => console.log(6));
});//当resolve()函数执行时才能执行
6.2.1执行同步任务
console.log(5);打印5
var p2=new Promise((n1,n2)=>{n1(20)})
打印 5
6.3添加异步宏任务
setTimeout(()=>{console.log(9)},0)
setTimeout(() => console.log(6));
6.4添加异步微任务
p1.then(() => console.log(2));
p2.then(() => console.log(8));
6.5执行异步微任务
p1.then(() => console.log(2));打印2
p2.then(() => console.log(8));打印8
打印 2 8
7.执行异步宏任务
setTimeout(()=>{console.log(9)},0)
7.1执行同步任务
console.log(9)
打印9
8.执行异步宏任务
setTimeout(() => console.log(6));
8.1执行同步任务
console.log(6)
打印6
9.因此打印 1740352896
总结
总结:宏任务先运行微任务后运行
步骤:
1.先执行第一轮宏任务(脚本)中的代码:同步~微任务~下一轮宏任务中的代码
2.宏任务中:同步~微任务~下轮排队的宏任务
3.下轮排队的宏任务中:执行同步~执行微任务~遇到宏任务继续排队~执行下轮排队的宏任务
4.下轮排队的宏任务中:执行同步~执行微任务~遇到宏任务继续排队~执行下轮排队的宏任务
5.下轮排队的宏任务中:执行同步~执行微任务~遇到宏任务继续排队~执行下轮排队的宏任务
6.按照这个步骤执行,知道代码跑完