1.Promise
1.简介
Promise,简单来讲就是一个容器,里面保存着某个将来才会结束的时间(一般是一个异步操做的结果)
Promise对象的基本语法:
new Promise((resolve,reject) => {前端
//.....
});数组
从语法上来讲,Promise是一个对象,从它能够获取异步操做的消息。
基本语法:
let p = new Promise((resolve,reject) => {promise
//... resolve('success')
});浏览器
p.then(result => {dom
console.log(result);//success
});异步
Promise对象特色和三个状态:async
这里写图片描述函数
例如:
let p = new Promise((resolve,reject) => {学习
//... resolve('success'); console.log('after resolve'); reject('error');
});测试
p.then(result => {
console.log(result);
});
p.catch(result => {
console.log(result);
})
运行结果:
after resolve
success
resolve下面的语句实际上是能够执行的,那么为何reject的状态信息在下面没有接受到呢?这就是由于Promise对象的特色:状态的凝固。new出一个Promise对象时,这个对象的起始状态就是Pending状态,在根据resolve或reject返回Fulfilled状态/Rejected状态。
2.
这里写图片描述
Then分别接受resolve和reject的信息,有三种参数形式,第三种比较“怪异”,只用来接收作reject处理。
eg:
let p = new Promise((resolve,reject) => {
//... let random = Math.random();//小于1大于0 if(random > 0.4) { resolve('random > 0.4'); }else { reject('random <= 0.4'); }
});
p.then(result => {
console.log('resolve',result);
}, result => {
console.log('reject',result);
});
3.链式调用
咱们来执行一段代码:
let p = new Promise((resolve,reject) => {
reject('reject');
});
let resultP = p.then(null,result => {
console.log(result);
});
console.log(resultP);
结果:
Promise { <pending> }
reject
js的执行顺序就是这样,同步->异步->回调,在同步执行的时候,Promise对象还处于pending的状态,也说明了这个then返回的是一个Promise对象。
并且必须在then里面给一个返回值,才能继续调用,不然undefined。
eg:
let p = new Promise((resolve,reject) => {
reject('error');
});
let resultP = p.then(null,result => {
console.log(result); return 123;
});
// console.log(resultP);
resultP.then(tmp => {
console.log(tmp);
})
结果:
error
123
4.catch
这里写图片描述
eg:
let p = new Promise((resolve,reject) => {
reject('error');
});
p.catch(result => {
console.log(result);
})
那这个catch的返回值是什么呢:
和上面then是同样的。
5.Promise.resolve()
这里写图片描述
传一个普通的对象:
// let p1 =Promise.resolve(123);
let p1 =Promise.resolve({name:'xixi',age:'xxxx'});
p1.then(result => {
console.log(result);
});
若是是Promise对象呢,直接返回
let p = new Promise((resolve,reject) => {
setTimeout(() => { resolve('success'); },500);
});
let pp = Promise.resolve(p);
pp.then(result => {
console.log(result);
});
console.log(pp == p);
结果:
true
success
6.Promise.reject()
这里写图片描述
eg:
let p = Promise.reject(123);
console.log(p);
p.then(result => {
console.log(result);
}).catch(result => {
console.log('catch',result);
})
结果:
Promise { <rejected> 123 }
catch 123
7.Promise.all()
这里写图片描述
eg:
let p1 = Promise.resolve(123);
let p2 = Promise.resolve('hello');
let p3 = Promise.resolve('success');
Promise.all([p1,p2,p3]).then(result => {
console.log(result);
})
结果:
[ 123, 'hello', 'success' ]
成功以后就是数组类型,当全部状态都是成功状态才返回数组,只要其中有一个的对象是reject的,就返回reject的状态值。
eg:
let p1 = Promise.resolve(123);
let p2 = Promise.resolve('hello');
let p3 = Promise.resolve('success');
let p4 = Promise.reject('error');
// Promise.all([p1,p2,p3]).then(result => {
// console.log(result);
// });
Promise.all([p1,p2,p4]).then(result => {
console.log(result);
}).catch(result => {
console.log(result);
});
结果:
error
又一个eg:
//用sleep来模仿浏览器的AJAX请求
function sleep(wait) {
return new Promise((res,rej) => { setTimeout(() => { res(wait); },wait); });
}
let p1 = sleep(500);
let p2 = sleep(500);
let p3 = sleep(1000);
Promise.all([p1,p2,p3]).then(result => {
console.log(result); //..... //loading
});
8.Promise.race
这里写图片描述
和all一样接受多个对象,不一样的是,race()接受的对象中,哪一个对象返回的快就返回哪一个对象,就如race直译的赛跑这样。若是对象其中有reject状态的,必须catch捕捉到,若是返回的够快,就返回这个状态。race最终返回的只有一个值。
eg:
//用sleep来模仿浏览器的AJAX请求
function sleep(wait) {
return new Promise((res,rej) => { setTimeout(() => { res(wait); },wait); });
}
let p1 = sleep(500);
let p0 = sleep(2000);
Promise.race([p1,p0]).then(result => {
console.log(result);
});
let p2 = new Promise((resolve,reject) => {
setTimeout(()=>{ reject('error'); },1000);
});
Promise.race([p0,p2]).then(result => {
console.log(result);
}).catch(result => {
console.log(result);
});
500
error
9.异常处理
这里写图片描述
为何说安静,一个例子,Pormise内部的错误外界用try-catch捕捉不到
eg:
try {
let p = new Promise((resolve, reject) => { throw new Error("I'm error"); // reject(new Error("I'm Error")); });
}catch(e) {
console.log('catch',e);
}
结果什么都没打印。
可是抛出的错误能够经过catch来捕捉:
// try {
let p = new Promise((resolve, reject) => { throw new Error("I'm error"); // reject(new Error("I'm Error")); });
// }catch(e) {
// console.log('catch',e);
// }
p.catch(result => {
console.log(result);
});
这样就捕捉到错误。因此:
这里写图片描述
2.Async-Await
1.简介:
这里写图片描述
这里写图片描述
async和await在干什么,async用于申明一个function是异步的,而await能够认为是async wait的简写,等待一个异步方法执行完成。
2.基本语法
这里写图片描述
在Chrome里申明这样一个函数,能够在控制台看到返回的其实就是一个Promise对象。
扩展须要了解的就是Chrome如今也支持asyncFunction,能够在Chrome控制台测试:
console.log(async function(){}.constructor);
ƒ AsyncFunction() { [native code] }
3.规则
这里写图片描述
如图,await放在普通函数里是会报错的。
这里写图片描述
eg:
async function demo() {
let result = await Promise.resolve(123); console.log(result);
}
demo();
4.应用
Promise虽然一方面解决了callback的回调地狱,可是相对的把回调“纵向发展”了,造成了一个回调链。eg:
function sleep(wait) {
return new Promise((res,rej) => { setTimeout(() => { res(wait); },wait); });
}
/*
let p1 = sleep(100);
let p2 = sleep(200);
let p =*/
sleep(100).then(result => {
return sleep(result + 100);
}).then(result02 => {
return sleep(result02 + 100);
}).then(result03 => {
console.log(result03);
})
控制台:
300
后面的结果都是依赖前面的结果。
改为async/await写法就是:
async function demo() {
let result01 = await sleep(100); //上一个await执行以后才会执行下一句 let result02 = await sleep(result01 + 100); let result03 = await sleep(result02 + 100); // console.log(result03); return result03;
}
demo().then(result => {
console.log(result);
});
由于async返回的也是promise对象,因此用then接受就好了。
结果:
300
须要注意的就是await是强制把异步变成了同步,这一句代码执行完,才会执行下一句。
5.错误处理
这里写图片描述
若是是reject状态,能够用try-catch捕捉
eg:
let p = new Promise((resolve,reject) => {
setTimeout(() => { reject('error'); },1000);
});
async function demo(params) {
try { let result = await p; }catch(e) { console.log(e); }
}
demo();
结果:
error
这是基本的错误处理,可是当内部出现一些错误时,和上面Promise有点相似,demo()函数不会报错,仍是须要catch回调捕捉。这就是内部的错误被“静默”处理了。
let p = new Promise((resolve,reject) => {
setTimeout(() => { reject('error'); },1000);
});
async function demo(params) {
// try { let result = name; // }catch(e) { // console.log(e); // }
}
demo().catch((err) => {
console.log(err);
})
6.注意你的并行执行和循环
好比上面的例子:
这里写图片描述
若是这三个是你想异步发出的AJAX请求,在这段代码里实际上是同步的,第一个发出去才会发第二个,因此async/await须要谨慎使用。
这里写图片描述
如今有一些forEach或者map的循环里,好比在forEach里使用await,这时候的上下文就变成了array,而不是async function,就会报错。这时候你就要想到是什么错误。
以上为本期介绍,您能够关注个人公众号,关注更多前端知识,还有前端大群一块儿交流学习!