Promise知识点

1、async / await

前面添加了async的函数在执行后都会自动返回一个Promise对象

function fn() {
    return 'leo';
}
console.log(fn());   // 'leo'

添加async后

async function fn() {
    return 'leo';   // Promise.resolve('leo')
}
console.log(fn());   // Promise对象

async函数中使用await,那么await处的代码就会变成同步的,即只有等await后面的Promise执行完成得到结果才会继续往下执行,await意为等待

function timeout() {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(1);
            resolve();
        }, 1000);
    })
}
 
async function fn() {
    await timeout();   // 执行完成才继续往下执行
    console.log(2);
}
 
fn();   // 不加async和await是 2、1,加了是 1、2

注意:

1、await 只能在 async 标记的函数内部使用,单独使用会触发 Syntax error;

2、await后面需要跟异步操作,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数。
 

2、Promise.prototype.finally()

Promise执行时,无论结果是fulfilled或者是rejected,在执行then()或catch()后,都会执行finally()指定的回调函数,可以避免同样的语句需要在then()和catch()中各写一次的情况

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success');
    }, 1000);
}).then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);
}).finally(() => {   // 无论Promise结果是then(),即resolve;还是catch(),即reject,最后都会执行finally()
    console.log('finally');
})

 如每次请求发送完毕,就需要关闭loading提示框,不管请求成功或是失败,这个loading都需要关闭掉,这时把关闭loading的代码写在finally里再合适不过了。

3、Promise.allSettled()

已知Promise.all() 具有并发执行异步任务的能力。但它的最大问题就是如果其中某个任务出现异常(reject),所有任务都会挂掉,且直接进入reject 状态。

如页面上有三个请求,分别请求不同的数据,如果使用Promise.all(),一个接口服务异常,整个都是失败的,都无法渲染出数据。

我们想要在并发任务中,无论一个任务正常或者异常,都会返回对应的的状态,则可以使用

let promise1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("promise1");
    }, 3000);
  });
};
let promise2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("promise2");
    }, 1000);
  });
};
let promise3 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("error promise3");
    }, 2000);
  });
};
 
// 使用Promise.all,则会走到catch里面,因为promise3是reject
Promise.all([promise1(), promise2(), promise3()])
  .then((res) => {
    console.log(res); 
  })
  .catch((error) => {
    console.log("error", error);   // error promise3 
  });
  
// 使用Promise.allSettled,不管有没有错误,三个状态都会返回,不会走到catch
Promise.allSettled([promise1(), promise2(), promise3()])
  .then((res) => {
    console.log(res);  
    // [
    //    {status: 'fulfilled', value: 'promise1'}, 
    //    {status: 'fulfilled', value: 'promise2'},
    //    {status: 'rejected', reason: 'error promise3'}
    // ]
  })
  .catch((error) => {
    console.log("error", error); 
  });

4、Promise.any() 和 AggregateError

Promise.any 与 Promise.all() 正好相反。如果任何承诺得到解决, Promise.any() 将被触发。

另一方面, Promise.all() 将等到所有承诺都得到解决。以下是 any()、all() 和 allSettled() 的区别。

any() — 如果至少有一个承诺被解决,这将执行,如果所有承诺都被拒绝,则将拒绝。即哪个resolve快就执行哪个。

all() — 如果所有承诺都得到解决,这将执行,如果至少一个承诺被拒绝,则将拒绝。

allSettled() — 如果所有承诺都已解决或被拒绝,这将执行。
 

 
// 创建一个Promise
const promise1 = new Promise((resolve, reject) => {
    // 2秒后resolve()
    setTimeout(() => resolve("The first promise has been resolved."), 2000);
});
 
// 创建一个Promise
const promise2 = new Promise((resolve, reject) => {
    // 1秒后resolve()
    setTimeout(() => resolve("The second promise has been resolved."), 1000);
});
 
// 创建一个Promise
const promise3 = new Promise((resolve, reject) => {
    // 3秒后resolve()
    setTimeout(() => resolve("The third promise has been resolved."), 3000);
});
 
(async function () {
    const data = await Promise.any([promise1, promise2, promise3]);
    // promise2最短时间resolve()
    console.log(data);     // The second promise has been resolved.
})();

如果所有 Promise 都被拒绝,则会抛出 AggregateError 异常。 

// 创建一个Promise
const promise1 = new Promise((resolve, reject) => {
    // 1s后reject()
    setTimeout(() => reject("The first promise has been rejected."), 1000);
});
 
// 创建一个Promise
const promise2 = new Promise((resolve, reject) => {
    // 0.5s后reject()
    setTimeout(() => reject("The second promise has been rejected."), 500);
});
 
// 处理异常
(async function () {
    try {
        const data = await Promise.any([promise1, promise2]);
        console.log(data);
    } catch (error) {
        // 如果所有的Promise都是reject()
        // 捕获aggregate errors.
        console.log("Error: ", error);
    }
})();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值