Promise
简单来说就是一个容器,里面保存着某个未来才会结束的时间,通常是一个异步操作的结果。
它有三种状态:pending(执行中)、success(成功)、rejected(失败)
resolve作用:
将 Promise 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
reject作用:
将 Promise 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。基本用法:
let fn = new Promise((resolve,reject) => {
if(true){
resolve('success');
} else {
reject('error')
}
})
fn.then(()=>{
// 成功回调
console.log('成功')
}).catch(()=>{
// 失败回调
console.log('失败')
})
Promise常用拓展:
当需要等多个请求完成后再执行下一步时,可通过 Promise.all 进行处理,例:
let p1 = new Promise((resolve, reject) => { resolve('成功111') }) let p2 = new Promise((resolve, reject) => { resolve('成功222') }) Promise.all([p1, p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error) })
执行结果:
注:
1. 只有当全部执行结果都为 resolve 的情况下,才会执行 then(),反之,只要有一个返回为 reject 便不会执行then(),仅执行 catch() 内的方法;
2. Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的。
async
作为一个关键字放在函数的前面,表示该函数是一个异步函数
async function asyncFn(){ return "helloworld"; } asyncFn().then((result)=>{ console.log(result); }); console.log(asyncFn()); console.log("我在后面"); // Promise { 'helloworld' } // 我在后面 // helloworld
由此可见,异步函数先执行,但是它并没有阻塞后面的代码执行。
async 总是返回一个 Promise
1. 没有显示 return,相当于return Promise.resolve(undefined);
2. return 非Promise的数据data,相当于return Promise.resolve(data);
3. return Promise, 会得到Promise对象本身
因此,async 异步函数其后面可以直接调用 then 方法,函数内部 return 返回的值,会成为 then 回调函数的参数;
函数内部抛出的错误,会被then的第二个函数或catch方法捕获到, 例:
// 抛出错误示例 async function fn(){ throw new Error('出错了'); } fn().then( v => console.log(v), e => console.log(e) // Error: 出错了 )
await
await 即等待,用于等待一个Promise对象。 它只能在异步函数 async 中使用,否则会报错 。
await 的返回值不是Promise对象而是Promise对象处理之后的结果。
await 的返回值不是Promise对象而是Promise对象处理之后的结果。
await 表达式会暂停当前 async 函数的执行,需等待Promise处理完成后才会向下继续执行。
看个例子就完全明白了:
async asyncFn(){ let fn = ()=>{ return new Promise((resolve) => { setTimeout(() => { console.log('延时2秒触发') resolve(); }, 2000); }) } let i=0 while (i<5){ if(i==2) { await fn() } console.log(i) i++ } }
执行结果:
错误捕获
let p = new Promise((resolve,reject) => { setTimeout(() => { reject('返回失败测试'); },1000); }); async function fn() { try { let result = await p; console.log(result) } catch(e) { console.log(e); // 返回失败测试 } } fn();
三则区别大致如下:
1. promise是ES6,async/await是ES7
2. async/await可以处理多个promise组成的.then链,不用重复嵌套,代码更洁简优雅。
3. reject状态:
promise错误可以通过catch来捕捉;
async/await既可以用.then又可以用try-catch捕捉。