目录
一、promise的理解和使用
1、promise是js中进行异步编程的新的解决方案。
2、具体表达:
3、promise的状态改变
4、promise的基本使用
5、promise的api
6、如何改变promise的状态
7、改变promise状态和指定回调函数,谁先谁后?
8、promise.then()返回新的promise的结果状态由什么决定?
9、promise如何串联多个操作任务?
10、promise值穿透
11、 async与await
(1)、从语法上来说:promise是一个构造函数。
(2)、从功能上来说:promise对象用来封装一个异步操作并可以获取其结果。
promise有三种状态:pending、resolved,rejected
一个promise对象只能改变一次,是不可逆的,pending改变resolved就不能改变为rejected,pending改变rejected就不能改为resolved。
(1)、创建一个promise对象
(2)、执行异步操作任务
(3)、如果成功了,调用resolve()函数对象,失败了,调用reject()函数对象。
(4)、使用then接受成功的value数据和失败的reason数据
(1)、promise()构造函数:promise(excutor){}
excutor函数:同步执行(resolve,reject)=>{}
resolve():内部定义成功的回调函数value=>{}
reject():内部定义失败的回调函数reason=>{}
excutor会在promise内部立即同步回调,异步操作在执行器中执行。
let p = new Promise((resolve, reject) => {
console.log('excutor', '执行excutor函数');
resolve(1)
reject()
})
p.then((value) => {
console.log(value), (reason) => { console.log(reason); }
})
console.log('打印1');
结果:
(2)、promise.prototype.then()方法:(onresolved,onrejected)=>{}
onresolved:成功的回调函数,(value)=>{}
onrejected:失败的回调函数,(reason)=>{}
指定用于得到成功的value成功回调,得到是失败的reason失败回调,返回一个新的promise对象。
let p = new Promise((resolve, reject) => {
resolve(1)
reject()
})
p.then((resolve) => {
console.log('成功的回调');
}, (reject) => {
console.log('失败的回调');
})
console.log(p);
结果:
(3)、promise.prototype.catch()方法:(onrejected)=>{}
onrejected函数:失败的reason回调函数,相当于then(undefined,onrejected)
let p = new Promise((resolve, reject) => {
reject(1)
})
p.catch((reason) => {
console.log('失败的回调' + reason);
})
//等价于
p.then((undefined) => { }, (reason) => {
console.log('失败的回调' + reason);
})
结果:
(4)、promise.resolve()方法:(value)=>{}
value:成功的数据和promise对象,返回一个成功的promise对象
(5)、promise.reject()方法:(reason)=>{}
reason:失败的数据和promise对象,返回一个失败的promise对象
(6)、promise.all()方法:(promise)=>{}
包含n个promise的数组,返回一个promise,只有所有的promise成功才成功,只要有一个promise失败就失败。
let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = Promise.reject(3)
let p4 = Promise.all([p1, p2, p3])
p4.then((value) => {
console.log('成功的回调');
}, (reason) => {
console.log('失败的回调');
})
结果:
(7)、promise.rece()方法:(promise)=>{}
包含n个promise的数组,返回一个promise对象,第一个完成的promise的结果状态就是最终的结果状态。
let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = Promise.reject(3)
let p4 = Promise.race([p1, p2, p3])
p4.then((value) => {
console.log('成功的回调');
}, (reason) => {
console.log('失败的回调');
})
结果:
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 1000)
})
let p3 = new Promise((resolve, reject) => {
reject(3)
})
let p4 = Promise.race([p1, p2, p3])
p4.then((value) => {
console.log('成功的回调' + value);
}, (reason) => {
console.log('失败的回调' + reason);
})
结果:
如何改变promise的状态:
(1)、resolve(value):如果当前是pendding就会变为resolved
let p = Promise.resolve(1)
p.then((value) => { console.log('成功的回调' + value); })//成功的回调1
(2)、reject(reason):如果当前是pendding就会变为rejected
let p = Promise.reject(1)
p.catch((reason) => { console.log('失败的回调' + reason); })//失败的回调1
(3)、抛出异常:如果当前是pendding就会变为rejected
let p = new Promise((resolve, reject) => {
throw new Error('抛出异常')
})
p.then((value) => { console.log('成功的回调' + value) },
(reason) => { console.log('成功的回调' + reason) })//成功的回调Error: 抛出异常
(1)、都有可能,正常情况下,先指定回调函数,后改变promise状态,但是也可以先改变promise状态,再指定回调函数。
(2)、如何先改变状态,再指定回调函数
1)、在执行器中直接调用resolve或者reject
let p = new Promise((resolve, reject) => {
resolve(1)
})
p.then((value) => { console.log(value); }, () => { })//1
2)、使用异步调用then
let p = new Promise((resolve, reject) => {
resolve(1)
})
setTimeout(() => { p.then((value) => { console.log(value); }, () => { }) }, 100)//1
3)、什么时候才能得到数据
a、如果先指定回调,那么回调函数就会被先保存起来,当pending状态发生改变时,就会立即调用回调函数。
b、如果先指定状态,那么当状态发生改变时,pending状态就会保存起来,当指定回调时,就会调用回调函数。
由then()指定的回调函数执行的结果决定。
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
reject(1)
}).then((value) => {
console.log('resolved1', value);
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
return 2
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
return Promise.resolve(3)
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
return Promise.reject(4)
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
throw 1
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
new Promise((resolve, reject) => {
resolve(1)
}).then((value) => {
console.log('resolved1', value);
return new Error('抛出异常')
}, (reason) => {
console.log('rejected1', reason);
}).then((value) => {
console.log('resolved2', value);
}, (reason) => {
console.log('rejected2', reason);
})
结果:
(1)、promise的then返回一个新的promise,可以看成then 的链式调用。
(2)、通过then的链式调用串联多个同步任务和异步任务。
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
console.log('执行异步任务1');
}, 100)
}).then((value) => {
console.log('接受到异步任务一的值' + value);
return new Promise((resolve, reject) => {
resolve(2)
console.log('执行异步任务2');
})
}).then((value) => {
console.log('接受到异步任务二的值' + value);
})
结果:
new Promise((resolve, reject) => {
reject(1)
}).then((value) => {
console.log(value + '成功的回调');
}).then((value) => {
console.log(value + '成功的回调');
}).then((value) => {
console.log(value + '成功的回调');
}).catch((reason) => {
console.log(reason + '失败的回调');
})
结果:
这串代码等价于
new Promise((resolve, reject) => {
reject(1)
}).then((value) => {
console.log(value + '成功的回调');
}, (reason) => { throw 1 }
).then((value) => {
console.log(value + '成功的回调');
}, (reason) => { throw 1 }
).then((value) => {
console.log(value + '成功的回调');
}, (reason) => { throw 1 }
).catch((reason) => {
console.log(reason + '失败的回调');
})
当前then无法接受上一个promise传下来的值时,就会从上往下开始依次查找对应关系的值,如果无法找到,则会报错。
(1)、async函数
1)、函数的返回值为promise对象
2)、promise对象的结果由async函数执行的返回值决定
async function fn1() {
return 1
}
async function fn2() {
return Promise.resolve(2)
}
async function fn3() {
return Promise.reject(3)
}
async function fn4() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(4)
})
})
}
async function fn5() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(5)
})
})
}
console.log(fn1());
console.log(fn2());
console.log(fn3());
console.log(fn4());
console.log(fn5());
结果:
(2)、await表达式
1)、await右侧的表达式一般为promise对象,当也可以是其他的值
2)、如果表达式是promise对象,await返回的是promise成功的值
3)、如果表达式是其他的值,直接将此值作为await的返回值
async function fn1() {
return 1
}
async function fn2() {
return Promise.resolve(2)
}
async function fn3() {
return Promise.reject(3)
}
async function fn4() {
let res1 = await fn1()
let res2 = await fn2()
try {
let res3 = await fn3()
console.log(res3);
} catch (error) {
console.log(error);
}
console.log(res1);
console.log(res2);
}
fn4()
结果:
注意:await必需写在async函数中,当async函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try catch捕获处理