Promise

54 阅读3分钟

Promise 的特征

  1. promise总共三个状态 pending fulfilled rejected 这三个状态一旦产生就不会再更变
  2. then和catch方法会返回一个新的Promise
  3. catch不论上层的哪一个都可捕获错误情况
  4. Promise中任意一个非Promise的值都会被包裹未Promise,eg. return 1 ===》 return Promise.resolve(1);
  5. Promise的then和catch可以被调用多次,但如果Promise的状态一经变化且返回对应的数据时,后续的每次对其的then和catch都可拿到该值
  6. .then或者.catch中return一个error对象并不会抛出错误,所以不会被后续的.catch捕获。
  7. .then或.catch返回的值不可为promise本身,否则会导致死循环
  8. .then或.catch的参数期望是函数,非函数会导致值透传
Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log)
//1 因第二个和第三个的.then传输非函数
  1. then方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch是.then第二个参数的简便写法。
  2. finally方法也是返回一个Promise,他在Promise结束的时候,无论结果为resolved还是rejected,都会执行里面的回调函数。
  3. finally()方法不管Promise对象最后的状态如何都会执行,且他会等待所有的promise执行完成后再执行
  4. finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected的
  5. 它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常的Promise对象
  6. 当前的微任务未执行完成不会进行下一个宏任务
  7. 如下用asyncawait的写法被调用后会变成Promise.resolve(data)的情况,可以减少请求量
// 获取灰度列表: 仅请求一次灰度接口
async function getUserGreyGroups() {
  const response = Fetch<number[]>({
    ...API.Admin.UserGroups(),
    method: 'GET',
    rawError: true,
    credentials: 'omit',
  });
  console.log('fetch user groups');
  const result = await response;
  return result ?? [];
}

export const userGreyGroups = getUserGreyGroups();
console.log(userGreyGroups, 'userGreyGroups');
  1. 无论有多少个.then,最终取得then的值都会是上一个Promise的所有then的最后一个then的结果
new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
    return new Promise((resolve) => {
      setTimeout(() => {
        console.log('setTimeout');
        resolve('success');
      }, 1000);
    });
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });
//1
//Promise {<pending>}
//setTimeout
//in permission success执行完该内部的
// undefined
// finally

.then获取的永远是上一个里的promise最终fulfilled的结果,可能会有多个.then,但是会是取的最后一个的值
finally执行是在上一个then不是pending状态的时候才会执行,return获取的是最终被resolve的值

任何promise里所return的数据如果不是promise会隐式转换为Promise.resolve()使数据都为Promise
Promise里的return会读取return后执行语句内Promise状态为完成的数据

在当前的微任务没有执行完成时,是不会执行下一个宏任务的。,因时序问题导致的打印也会有一定的不对

题1:

new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
   
    return new Promise((resolve) => {
      setTimeout(() => {
        console.log('setTimeout');
        resolve('success');
      }, 1000);
    }).then((res) => 'next');
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });

new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
      return new Promise((resolve) => {
      setTimeout(() => {
        console.log('setTimeout');
        resolve('success');
      }, 1000);
    }).then((res) => 'next');
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });
//这里是因为时序问题,因为第一个打印的快一些执行的就快导致的
1
1
setTimeout
in permission next
undefined
finally
setTimeout
in permission next
undefined
finally
new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
    return 'next';
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });

new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
    return 'next';
  
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });
1
1
in permission next
in permission next
undefined
undefined
finally
new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);

    return new Promise((resolve) => {

      console.log('setTimeout');
      resolve('success');

    }).then((res) => 'next');
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });

new Promise((resolve) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);

    return new Promise((resolve) => {

      console.log('setTimeout');
      resolve('success');

    }).then((res) => 'next');
  })
  .then((res) => {
    console.log('in permission', res);
  })
  .then((res) => {
    console.log(res);
    return 4;
  })
  .finally(() => {
    console.log('finally');
  });
1
setTimeout
1
setTimeout
in permission next
in permission next
undefined
undefined
finally
finally