一、promise
// resolve代表成功 reject失败 都是一个函数
let p = new Promise(function(reslove,reject){
//reslove('成功') //状态由等待变为成功,传的参数作为then函数中成功函数的实参
reject('失败') //状态由等待变为失败,传的参数作为then函数中失败函数的实参
})
//then中有2个参数,第一个参数是状态变为成功后应该执行的回调函数,第二个参数是状态变为失败后应该执行的回调函数。
p.then((data)=>{
console.log('成功'+data)
},(err)=>{
console.log('失败'+err)
})
如果then中返回了一个promise 会将promise的结果继续传给第二then中(如果结果是将状态改成成功就走下一个then的成功回调,状态改为失败就走下一个then的失败回调)
function read( content ) {
return new Promise(function( reslove,reject ) {
setTimeout(function(){
if(content>4){
resolve(content)
}else{
reject('小于4')
}
},1000)
})
}
read(1).then(( data )=>{
console.log(data)
},( err )=>{
console.log(err) //小于4
return read(2) //将状态改为了失败
})
.then(( data )=>{
console.log('data',data)
},( err )=>{
console.log(err) //小于4
})
catch的用法
catch可以实现错误的捕获 一般写在最后,如果上面有自己的err会走自己的error。如果没有写就会走到catch
let p = new Promise(function(resolve,reject){
reject('失败')
});
p.then((data)=>{
},(err)=>{
throw Error('错误')
})
.then((data)=>{
},(err)=>{
console.log(err+'自己的err') //走自己的(输出:Error: 错误自己的err)
throw Error('错误自己抛出的')
})
.then((data)=>{
//没有自己的失败处理函数,走catch
}).catch(e=>{
console.log(e+'公共的err') //输出:Error: 错误自己抛出的公共的err
})
all的用法
Promise.all方法执行后返回的依旧是promise, all两个全成功才表示成功 。
function read(content) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(content)
}, 1000)
})
}
let result = Promise.all([read(1), read(2)]);
result.then((data) => {
console.log(data) //[ 1, 2 ]
})
race的用法
如果先成功了那就成功了, 如果先失败了那就失败了
function read(content) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if(content>4){
resolve(content)
}else{
reject(content)
}
}, 1000*content)
})
}
let result = Promise.race([read(5), read(2)]);
result.then((data) => {
console.log('成功'+data)
},(err)=>{
console.log('失败'+err) //失败2
})
二、async和await
基本用法:
function 摇色子(){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
setTimeout(()=>{
resolve(sino)
},3000)
})
}
async function test(){
let n =await 摇色子()
console.log(n)
}
test()
- 获取失败的结果
function 摇色子(猜测){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
if(sino > 3){
if(猜测 === '大'){
resolve(sino)
}else{
reject(sino)
}
}else{
if(猜测 === '大'){
reject(sino)
}else{
resolve(sino)
}
}
setTimeout(()=>{
resolve(sino)
},300)
})
}
async function test(){
try{
//把await及获取它的值的操作放在try里
let n =await 摇色子('大')
console.log('赢了' + n)
}catch(error){
//失败的操作放在catch里
console.log('输了' + error)
}
}
test()
前面我们说了,async和await是处理then链的语法糖,现在我们来看看具体是怎么实现的:
假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。我们仍然用setTimeout来模拟异步操作:
/** * 传入参数 n,表示这个函数执行的时间(毫秒) * 执行的结果是 n + 200,这个值将用于下一步骤 */ function takeLongTime(n) { return new Promise(resolve => { setTimeout(() => resolve(n + 200), n); }); } function step1(n) { console.log(`step1 with ${n}`); return takeLongTime(n); } function step2(n) { console.log(`step2 with ${n}`); return takeLongTime(n); } function step3(n) { console.log(`step3 with ${n}`); return takeLongTime(n); }
现在用 Promise 方式来实现这三个步骤的处理。
function doIt(){ console.time('doIt'); let time1 = 300; step1(time1) .then((time2) => step2(time2)) .then((time3) => step3(time3)) .then((result) => { console.log(`result is ${result}`); console.timeEnd("doIt"); }) } doIt(); //执行结果为: //step1 with 300 //step2 with 500 //step3 with 700 //result is 900 //doIt: 1510.2490234375ms
输出结果 result
是 step3()
的参数 700 + 200
= 900
。doIt()
顺序执行了三个步骤,一共用了 300 + 500 + 700 = 1500
毫秒,和 console.time()/console.timeEnd()
计算的结果一致。
如果用 async/await 来实现呢,会是这样:
async function doIt() { console.time('doIt'); let time1 = 300; let time2 = await step1(time1);//将Promise对象resolve(n+200)的值赋给time2 let time3 = await step1(time2); let result = await step1(time3); console.log(`result is ${result}`); console.timeEnd('doIt'); } doIt(); //执行结果为: //step1 with 300 //step2 with 500 //step3 with 700 //result is 900 //doIt: 1512.904296875ms
显然我们用async/await简单多了
await 表达式的运算结果取决于它等的东西。
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
function testAsy(x){
return new Promise(resolve=>{setTimeout(() => {
resolve(x);
}, 3000)
}
)
}
async function testAwt(){
let result = await testAsy('hello world');
console.log(result); // 3秒钟之后出现hello world
console.log('tangj') // 3秒钟之后出现tangj
}
testAwt();
console.log('tangSir') //立即输出tangSir