同步与异步 / 初识Promise
javaScript 是一个单线程的语言
同步与异步
同步和异步是一种消息通知机制
只限于理解,不用于回答
同步:上一件事结束,才能去做下一件事
异步:上一件事没有做完,就可以做下一件事
- 同步阻塞
A调用B,B处理获得结果,A在过程中,一直等待B的处理结果
没有拿到结果之前,需要A一直等待,直到拿到结果,然后才会继续执行
let a = 10;
function fn(){
a = 20;
}
fn();
console.log(a);
- 异步非阻塞
事件,定时器,网络请求
A调用B,无需等待B的结果
B通过状态通知、回调等方式在完成后,通知B
let b = 20;
// 定时器为 异步
setTimeout(()=>{
b = 30;
},2000)
console.log(b)
let c = 10;
let img = new Image();
img.src = "http://img.mp.itc.cn/upload/20170213/cb5d90c0ab244b319ff1739ec3f5ec92_th.jpeg";
// onload 事件为 异步
img.onload = function(){
c = 20;
}
console.log(c) // =>(图片在加载同时)拿到 c 的原先数据 10
Promise基础
Promise对象 不是解决了异步的问题,而是改变了异步的写法
会自带返回值,返回一个对象
内部状态
- pending 等待中 ( 异步执行中 )
- fulilled( 实际上是该状态 )
resolved( 调用 ) 执行成功 调用 ---- resolve之后改变 - rejected 执行失败 ---- 调用reject 之后改变
let p = new Promise(function(resolve,reject){
// this 是在匿名函数中 指向window
console.log(this);
console.log(1);
// resolve 调用表示当前执行成功,then 中的 函数1 开始执行
// resolve("给then的数据");
// reject 调用表示当前执行失败,then 中的 函数2 开始执行
reject("失败的数据");
});
new Promise( promise的回调函数,在实例化的时候可以直接执行 )
- resolve( 传递参数给 执行成功后触发的函数 )
代表异步执行完成,并成功拿到结果 ---- 将 promise对象 的状态改为 resolve - reject( 传递参数给执行失败后 触发的函数 )
代表异步执行完成,但没有拿到结果 ---- 将promise对象的状态改为reject - resolve / reject 两种情况 二存一
then 方法
自带两个函数
promise.then( onFulfilled , onRejected )
p.then(function(res){
// this 指向 window ( this 存在于传递进来的匿名函数中)
console.log(this)
// res 接收的是 resolve(); 传过来的参数
// resolve 调用后 console.log 才会执行
console.log( res+ "异步处理结束后的结果");
},function(rej){
// rej 接收的是 reject(); 传过来的参数
// reject 调用后 console.log 才会执行
console.log(rej + "执行失败");
})
console.log(p)
then链式写法
let q = new Promise((resolve,reject)=>{
resolve(2);
});
// q1 接收的是q的返回的
let q1 = q.then((data) =>{
console.log("resolve");
return new Promise((resolve,reject) =>{
// 调用对象 决定 返回的Promise状态
// reject("emm")
resolve("emmm")
})
},(data)=>{
console.log("reject");
return {
n : 13
}
});
// q 的返回的 调用then 的变化
q1.then((data) =>{
console.log("q1的resolve")
},(data)=>{
console.log("q1的reject")
});
then 方法会返回一个新的Promise对象
新的 Promise 对象状态
- 默认情况:返回的是一个状态为 resolve 的Promise对象
- 当then 的回调函数 返回的是一个 非Promise对象
then 返回的是一个状态为 resolve(执行成功) 的Promise对象 - 当then方法 返回一个 Promise 对象时,
then的返回值也会变为 该状态的Promise对象
Promise动画示例
前端HTML准备
<style>
*{
margin: 0px;
padding: 0px;
}
#box{
width: 100px;
height: 100px;
background: purple;
border-radius: 50%;
position: absolute;
}
</style>
<div id="box"></div>
前端JS代码
/*
el 元素
attr 样式
val 目标样式 具体值
cb 当前动画结束要做的事情
*/
function move(el,attr,val){
// 当前值
let now = parseFloat(getComputedStyle(el)[attr]);
// 方向
let speed = (val - now) / Math.abs(val - now) *2;
return new Promise((resolve) => {
clearInterval(el.timer)
// 绑给元素 el.timer
el.timer = setInterval(()=>{
if (Math.abs(now - val) <= 0) {
clearInterval(el.timer);
resolve();
}else{
now += speed;
el.style[attr] = now + "px";
}
},20);
});
}
{
let box = document.querySelector("#box");
// 使用Promise 来完成回调
function boxMove(){
move(box,"left",150).then(()=>{
// 覆盖本应该返回的 Promise 对象
return move(box,"top",150);
}).then(()=>{
return move(box,"left",0);
}).then(()=>{
return move(box,"top",0);
}).then(()=>{
// 回调 不停地循环
boxMove()
})
}
boxMove();
}