什么是Promise

Promise 是一个构造函数,自身具有all, allSettled, resolve,reject, race 等方法,原型上有then, catch, finally等方法(因此我们通过 Promise 构造函数实例化的 实例仍然具有这些方法)

  1. console.log(Promise)
  2. -------------------------------------
  3. ƒ Promise()
  4. > all: ƒ all()
  5. > allSettled: ƒ allSettled()
  6. > any: ƒ any()
  7. > arguments: (...)
  8. > caller: (...)
  9. > length: 1
  10. > name: "Promise"
  11. > prototype: Promise
  12. catch: ƒ catch()
  13. constructor: ƒ Promise()
  14. finally: ƒ finally()
  15. then: ƒ then()
  16. Symbol(Symbol.toStringTag): "Promise"
  17. __proto__: Object
  18. > race: ƒ race()
  19. > reject: ƒ reject()
  20. > resolve: ƒ resolve()
  21. > Symbol(Symbol.species): (...)
  22. > Symbol(allSettled): ƒ (d)
  23. > get Symbol(Symbol.species): ƒ [Symbol.species]()
  24. > __proto__: ƒ ()
  25. > [[Scopes]]: Scopes[0]

image.png

Promise基本用法

then & catch

  1. function getNumber(){
  2. var p = new Promise(function(resolve, reject){
  3. //做一些异步操作
  4. setTimeout(function(){
  5. var num = Math.ceil(Math.random()*10); //生成1-10的随机数
  6. if(num<=5){
  7. resolve(num);
  8. }
  9. else{
  10. reject('数字太大了');
  11. }
  12. }, 2000);
  13. });
  14. return p;
  15. }
  16. // 写法一
  17. getNumber() // 函数执行返回一个Promise对象
  18. .then(
  19. function(data){ // resolve 函数, 异步任务执行成功的回调
  20. console.log('resolved');
  21. console.log(data);
  22. },
  23. function(reason, data){ // reject 函数, 异步任务执行失败的回调
  24. console.log('rejected');
  25. console.log(reason);
  26. }
  27. );
  28. // 写法二
  29. getNumber()
  30. .then(function(data){ // resolve 函数, 异步任务执行成功的回调
  31. console.log('resolved');
  32. console.log(data);
  33. })
  34. .catch(function(data){ // reject 函数, 异步任务执行失败的回调
  35. console.log('rejected');
  36. console.log(reason);
  37. })

all的用法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调

有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。

  1. function runAsync1(){
  2. let p1 = new Promise(function(resolve, reject){
  3. // 执行一些异步任务
  4. setTimeOut(function(){
  5. console.log('异步任务1执行完成');
  6. resolve('随便什么数据1')
  7. }, 2000)
  8. })
  9. return p1;
  10. }
  11. function runAsync2(){
  12. let p1 = new Promise(function(resolve, reject){
  13. // 执行一些异步任务
  14. setTimeOut(function(){
  15. console.log('异步任务2执行完成');
  16. resolve('随便什么数据2')
  17. }, 2000)
  18. })
  19. return p2;
  20. }
  21. function runAsync3(){
  22. let p1 = new Promise(function(resolve, reject){
  23. // 执行一些异步任务
  24. setTimeOut(function(){
  25. console.log('异步任务3执行完成');
  26. resolve('随便什么数据3')
  27. }, 2000)
  28. })
  29. return p3;
  30. }
  31. // 接受三个异步执行的函数,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面
  32. Promise.all([runAsync1(), runAsync2(), runAsync3()]).then((result)=>{
  33. console.log(result);
  34. // 异步任务1执行完成
  35. // 异步任务2执行完成
  36. // 异步任务3执行完成
  37. // ["随便什么数据1", "随便什么数据2", "随便什么数据3"]
  38. })

race的用法

谁跑的快,以谁为准执行回调

多个异步任务同时执行,如果有一个任务执行完成,执行回调函数,后续的任务正常执行,不在打印回调结果

  1. function runAsync1(){
  2. let p1 = new Promise(function(resolve, reject){
  3. // 执行一些异步任务
  4. setTimeOut(function(){
  5. console.log('异步任务1执行完成');
  6. resolve('随便什么数据1')
  7. }, 2000)
  8. })
  9. return p1;
  10. }
  11. function runAsync2(){
  12. let p1 = new Promise(function(resolve, reject){
  13. // 执行一些异步任务
  14. setTimeOut(function(){
  15. console.log('异步任务2执行完成');
  16. resolve('随便什么数据2')
  17. }, 2000)
  18. })
  19. return p2;
  20. }
  21. function runAsync3(){
  22. let p1 = new Promise(function(resolve, reject){
  23. // 执行一些异步任务
  24. setTimeOut(function(){
  25. console.log('异步任务3执行完成');
  26. resolve('随便什么数据3')
  27. }, 2000)
  28. })
  29. return p3;
  30. }
  31. Promise.race([runAsync1(), runAsync2(),runAsync3()]).then((result)=>{
  32. console.log(result);
  33. // 异步任务1执行完成
  34. // 随便什么数据1
  35. // 异步任务2执行完成
  36. // 异步任务3执行完成
  37. })

使用场景

可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作
请求图片任务、超时5s任务 两个任务 执行Promise.race() 如果超过5s图片任务还没有请求图片,则执行超时任务提升超时

  1. function getImg(){
  2. let p = new Promise(function(resolve, reject){
  3. let img = new Image();
  4. img.onload = function(){
  5. resolve(img)
  6. }
  7. img.src = 'https://cdn.nlark.com/yuque/0/2020/png/152077/1606703278597-fdcaa8e1-3394-463a-bac2-c2dcfa3df160.png';
  8. })
  9. return p;
  10. }
  11. function timeout(){
  12. let p = new Promise(function(resolve, reject){
  13. setTimeout(function(){
  14. reject('图片超时了')
  15. }, 5000)
  16. })
  17. return p;
  18. }
  19. Promise.race([getImg(), timeout()]).then(function(data){
  20. console.log(data);
  21. }).catch(function(error){
  22. console.log(error);
  23. })

参考