1.Promise的用途

Promise 是1976年的一种设计模式,是前端解决异步问题的统一方案
它很好的解决了下面三个问题:

  1. 规范回调的名字或顺序
  2. 拒绝回调地狱,让代码可读性更强
  3. 很方便地捕获错误

    2.如何创建一个 new Promise

    return new Promise((resolve,reject)=>{...})
    成功调用resolve,失败调用reject
    1. function(){
    2. return new Promise(function (resolve, reject) {
    3. // ...
    4. if (/* 异步操作成功 */){
    5. resolve(value);
    6. } else { /* 异步操作失败 */
    7. reject(new Error());
    8. }
    9. })
    10. }

    3.如何使用 Promise.prototype.then

    .then()方法可以添加多个回调函数(可进行链式操作)
    .then(success,fail)
    其中第一个参数是成功,也就是调用resolved状态的回调函数
    第二个参数是失败,也就是调用rejected状态的回调函数
    同时.then()里参数是可选的,可以只写一个
    1. var p1 = new Promise(function (resolve, reject) {
    2. resolve('成功')
    3. })
    4. p1.then(console.log, console.error) // "成功"
    5. // 链式使用
    6. p1
    7. .then()
    8. .then()
    9. .then(console.log, console.error)

    4.如何使用 Promise.all

    Promise.all(iterable)返回一个Promise实例
    返回值:
  • 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
  • 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise(注:Google Chrome 58 在这种情况下返回一个已完成)
  • 其它情况下返回一个处理中(pending)的Promise。之后会在所有的promise都成功,返回成功的值;或者有一个失败就返回失败

参数iterable
是一个可迭代对象,如ArrayString
Promise.all可以将多个Promise实例包装成一个新的Promise实例。
同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值(全部成功才成功,有一个失败就失败)

  1. let p1 = new Promise((resolve, reject) => {
  2. resolve('成功')
  3. })
  4. let p2 = 200
  5. let p3 = Promise.reject('失败')
  6. Promise.all([p1, p2]).then((result) => {
  7. console.log(result) // ["成功",200]
  8. }).catch((error) => {
  9. console.log(error)
  10. })
  11. Promise.all([p1,p3,p2]).then((result) => {
  12. console.log(result)
  13. }).catch((error) => {
  14. console.log(`error:${error}`) // 失败了,打出 '失败'
  15. })

不加后面的catch,让这个Promise失败,图示:
image.png
注:Promise.all()中哪个在前,哪个的结果就在前面,不会根据得到结果的时间顺序来排序

5.如何使用 Promise.race

Promise.race也是将多个Promise实例包装成一个新的Promise实例(race,就是竞赛的意思)
Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态
如果传的迭代是空的,则返回的promise永远等待

  1. let p1 = new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. resolve('one')
  4. },1000)
  5. // 等同于 setTimeout(resolve, 1000, 'one'),此法不推荐使用,有安全风险
  6. })
  7. let p2 = new Promise((resolve, reject) => {
  8. setTimeout(() => {
  9. resolve('two')
  10. }, 500)
  11. })
  12. Promise.race([p1,p2]).then(function(result){
  13. console.log(result)
  14. })
  15. // 'two'

6.Promise的执行顺序

Promise(微任务)的回调函数属于异步任务,会在同步任务之后执行

  1. console.log(1)
  2. setTimeout(function() {
  3. console.log(2);
  4. }, 0);
  5. new Promise(function (resolve, reject) {
  6. console.log(3)
  7. resolve(4);
  8. console.log(5)
  9. }).then(console.log);
  10. console.log(6);
  11. // 1 3 5 6 4 2
  • new Promise 里的是同步任务,立即执行
  • .then任务即为微任务,同步之后,普通异步之前
  • setTimeout为普通异步任务 ```javascript async function async1() { console.log(1); const result = await async2(); console.log(3); }

async function async2() { console.log(2); }

Promise.resolve().then(() => { console.log(4); });

setTimeout(() => { console.log(5); });

async1(); console.log(6); // 1 2 6 4 3 5 ```

  • async里面没有await为同步任务,遇到await暂停该函数执行,可以理解为一个.then回调