期约
Promise是ES6新增的引用类型Promise,可以使用new 操作符来实例化
期约是一个有状态的对象,有三种状态
1.待定(pending): 表示尚未开始或者正在执行中。
2.兑现(fulfilled,有时候也称为“解决”,resolved): 表示已经成功完成。
3.拒绝(rejected): 则表示没有成功完成,也就是已经失败。
Promise.resolve()
Promise.reject()
实现Thenable接口
在ECMScript暴露的异步结构中,任何一个对象都有同一个then()方法。
ECMScript的promise类型实现了Thenable接口
Promise.prototype.then()
异步函数
异步函数。“async await”(语法关键字)。让同步写的代码可以异步执行。
ES的async/await旨在解决异步结构组织代码的问题。
async用于声明异步函数
async function foo(){
console.log(1);
return 3
}
foo().then(console.log)
console.log(2); // 1 2 3
异步函数如果使用了return关键字返回值(如果没有返回undefined),这个值会被Promise.reslove()包装成一个期约对象。
async function foo(){
console.log(1);
}
foo().then(console.log)
console.log(2); // 1 2 undefined
当然直接返回一个期约对象也是可以的,效果一样。
await关键字可以暂停异步代码的执行,等待期约解决。
因为异步函数主要针对不会马上完成的任务,所以自然需要一种暂停和恢复的能力。
等待会抛出错误的同步操作,会返回拒绝的期约
async function foo(){
console.log(1)
await(()=>{throw 3;})()
}
foo.catch(console.log)
console.log(2)
1
2
3
async function foo(){
await Promise.reject(1);
console.log(3);
}
foo().catch(console.log)
console.log(2);
1
2
单独的Promise.reject()不会被异步函数捕获,而会抛出未捕获错误。不过,对拒绝的期约使用await则会释放(unwrap)错误值(将拒绝期约返回)
也就是要使用Peomise.reject(),需要await,异步函数才能将拒绝期约返回
Promise.all() 和 Promise.race()
Promise.all()
Promise.all()静态方法创建得期约会在一组期约全部解决之后再解决。这个静态方法接受一个可迭代对象,返回一个新期约。
let h = Promise.all([1,2,3]) // 直接作为期约解决之后的值
h.then(res=>console.log(res)) //[1,2,3]
如果所有期约都成功解决,则合成期约的解决值就是包含期约解决值得数组,按照迭代器顺序。
let p = Promise.all([
Promise.resolve(2),
Promise.resolve(3),
Promise.resolve(6)
])
p.then(res=>console.log(res)) // [2,3,6]
如果有期约拒绝,则合成的期约也会拒绝,第一个拒绝期约的理由会作为合成期约的理由,之后再拒绝期约不会影响最终期约拒绝理由,同样也不会影响后面的期约正常的拒绝操作。
Promise. race()
Promise.race()静态方法,该方法接收一个可迭代对象,返回一个集合中最先解决或拒绝的期约的镜像。不影响其他期约的进行,会静默处理。
let b = Promise.race([
new Promise((resolve,reject)=>setTimeout(()=>resolve(1),1000)),
Promise.resolve(2),
Promise.resolve(3)
])
b.then(res=>console.log(res)) //2
Promise.race()不会对解决拒绝的期约区别对待。无论是解决还是拒绝,只要是第一个落定的期约,Promise.race()就会包装其解决值或拒绝理由并返回新期约