ES6-Promise

ゞ 浴缸里的玫瑰 2022-05-15 07:52 374阅读 0赞

1. Promise的基础

(1)js的异步操作:

  1. a. ajax请求
  2. b. 浏览器事件
  3. c. 定时,setTime setInteval

(2)异步无法避免产生回调函数

  1. <script>
  2. //定时
  3. setTime(function(){
  4. })
  5. //事件
  6. add.addEventListener("click",function(){
  7. })
  8. //ajax
  9. xhr.addEventListener("readystartechange",function(){
  10. })
  11. </script>

(3)回调地狱:回调函数嵌套回调函数

  1. <script>
  2. //回调函数嵌套回调函数
  3. //现象
  4. var xhr = new XMLHttpRuquest();
  5. xhr.addEventListener("readystartechange",function(){
  6. xhr.responseText;//想要这个函数再次进行调用,则需要再写个函数
  7. var xhr = new XMLHttpRuquest();
  8. xhr.addEventListener("readystartechange",function(){
  9. //再次调用
  10. xhr.addEventListener("readystartechange",function(){
  11. })
  12. })
  13. })
  14. xhr.open();
  15. xhr.send();
  16. </script>

(4)以上回调函数嵌套函数,代码可读性差,解决方法:Promise,

解决回调地狱

像同步操作那样去执行异步的操作

Promise的构造函数:必须接受一个函数作为参数,函数可以接收参数,例如例子中的resolve

  1. <script>
  2. //Promise
  3. let p = new Promise(function(resolve){//接收参数
  4. console.log("成功执行");
  5. //调用参数,并没有输出进行中...需在下面进行调用
  6. resolve("进行中...");//函数
  7. console.log("执行完成");
  8. })
  9. console.log(p);//Promise { <state>: "fulfilled", <value>: "进行中..." }
  10. //resolve就相当于以下
  11. p.then(function(data){
  12. console.log(data);//输出:进行中...
  13. })
  14. </script>

2. Promise原理

(1)原理:

a. 一个Promise实例(对象)代表一个异步操作

  1. <script>
  2. //Promise
  3. let p = new Promise(function(resolve,reject){//resolve,reject必须叫这个名称,不是自定义的
  4. // 必须写异步操作
  5. setTimeout(function(){
  6. // 相当于函数的调用
  7. resolve("执行");
  8. },2000)
  9. })
  10. //相当于函数的声明
  11. p.then(function(res){
  12. console.log(res);//2秒之后输出:执行
  13. })
  14. </script>

b. promise通过状态去管理异步操作

pendding,进行中

  1. <script>
  2. //Promise
  3. let p = new Promise(function(resolve,reject){//resolve,reject必须叫这个名称,不是自定义的
  4. // 必须写异步操作
  5. setTimeout(function(){
  6. // 相当于函数的调用
  7. resolve("执行");
  8. },2000)
  9. })
  10. console.log(p);//Promise { <state>: "pending" }
  11. </script>

fulfilled,已完成

  1. <script>
  2. //=============状态fulfilled已完成===========
  3. let p3 = new Promise(function(resolve,reject){//resolve,reject必须叫这个名称,不是自定义的
  4. // 必须写异步操作
  5. setTimeout(function(){
  6. // 相当于函数的调用
  7. resolve("执行fulfilled");
  8. },2000)
  9. })
  10. setInterval(function(){
  11. console.log(p3);
  12. },3000)//Promise { <state>: "fulfilled", <value>: "执行fulfilled" }
  13. </script>

resolve(),函数执行之后

reject(),函数执行

rejected(),执行失败

  1. <script>
  2. //=============状态rejected执行失败===========
  3. let p4 = new Promise(function(resolve,reject){//resolve,reject必须叫这个名称,不是自定义的
  4. // 必须写异步操作
  5. setTimeout(function(){
  6. // 相当于函数的调用
  7. // resolve("执行rejected");
  8. reject();
  9. },2000)
  10. })
  11. setInterval(function(){
  12. console.log(p4);
  13. },3000)//Promise { <state>: "rejected" }
  14. </script>

总结:以一例子看

  1. <script>
  2. //Promise
  3. function timeout(){
  4. let randNum = Math.random() * 2;
  5. // let p = new Promise(function(resolve,reject){
  6. return new Promise(function(resolve,reject){
  7. setTimeout(function(){
  8. if(randNum > 1){
  9. resolve();
  10. }else{
  11. reject();
  12. }
  13. },randNum * 1000)
  14. });
  15. }
  16. // 方法一:先使用setInterval实现
  17. let p = timeout();
  18. setInterval(function(){
  19. console.log(p);
  20. },1000)//状态不确定
  21. //方法二:then()
  22. timeout.then(function(){
  23. console.log("成功");
  24. },function(){
  25. console.log("失败");
  26. })
  27. </script>

3. Promise实例

问题:三个接口:电影排行榜、电影详情内容、电影详情人信息,查找排行榜第一的电影的导演的家乡在哪

解答一:传统

  1. <body>
  2. <div id="main"></div>
  3. </body>
  4. <script>
  5. //排行榜
  6. let url01 = "http://api.unclealan.cn:4100/movie/top";
  7. // 电影详情
  8. let url02 = "http://api.unclealan.cn:4100/movie/subject/";
  9. // 电影人详情
  10. let url03 = "http://api.unclealan.cn:4100/movie/celebrity/";
  11. let message = "排行榜第一的电影是:"
  12. // 1. 排行榜
  13. let xhr01 = new XMLHttpRequest();
  14. // 检测是否成功
  15. xhr01.onload = function(){
  16. // console.log(xhr01.responseText);//输出一些json字符串
  17. // 解析
  18. let resObj = JSON.parse(xhr01.responseText);
  19. let id = resObj.subjects[0].id;
  20. console.log(resObj.subjects[0].id);
  21. console.log(resObj.subjects[0].title);
  22. message += resObj.subjects[0].title+ ";";
  23. //2. 电影详情
  24. let xhr02 = new XMLHttpRequest();
  25. //检测是否成功
  26. xhr02.onload = function(){
  27. let resObj = JSON.parse(xhr02.responseText);
  28. // console.log(resObj);
  29. let id =resObj.directors[0].id;
  30. console.log(id);
  31. message += "导演是:"+resObj.directors[0].name+ ";";
  32. //3. 电影详情人
  33. let xhr03 = new XMLHttpRequest();
  34. xhr03.onload = function(){
  35. let resObj = JSON.parse(xhr03.responseText);
  36. console.log(resObj.born_place);
  37. message += "老家是:"+resObj.born_place;
  38. document.querySelector("#main").innerHTML = message;
  39. // let name = resObj.avatars.born_place;
  40. }
  41. xhr03.onerror = function(){
  42. console.log("请求电影详情人失败");
  43. }
  44. xhr03.open("GET",url03+id);//显示http://api.unclealan.cn:4100/subject/:id
  45. xhr03.send();
  46. }
  47. xhr02.onerror = function(){
  48. console.log("请求电影详情失败");
  49. }
  50. xhr02.open("GET",url02+id);//显示http://api.unclealan.cn:4100/subject/:id
  51. xhr02.send();
  52. }
  53. xhr01.onerror = function(){
  54. console.log("请求电影排行榜失败");
  55. }
  56. xhr01.open("GET",url01);
  57. xhr01.send();
  58. </script>

解答二:Promise

  1. <body>
  2. <div id="main"></div>
  3. </body>
  4. <script>
  5. //1. 排行榜
  6. let url01 = "http://api.unclealan.cn:4100/movie/top";
  7. //2. 电影详情
  8. let url02 = "http://api.unclealan.cn:4100/movie/subject/";
  9. //3. 电影人详情
  10. let url03 = "http://api.unclealan.cn:4100/movie/celebrity/";
  11. let message = "排行榜第一的电影是:"
  12. // 1. 排行榜
  13. function getTopInfo(){
  14. return new Promise(function(resolve,reject){
  15. let xhr = new XMLHttpRequest();
  16. xhr.onload = function(){
  17. resolve(JSON.parse(xhr.responseText));
  18. }
  19. xhr.onerror = function(){
  20. reject("获取电影排行榜失败");
  21. }
  22. xhr.open("GET",url01);
  23. xhr.send();
  24. })
  25. }
  26. //2. 电影详情
  27. function getMovieInfo(id){
  28. return new Promise(function(resolve,reject){
  29. let xhr = new XMLHttpRequest();
  30. xhr.onload = function(){
  31. resolve(JSON.parse(xhr.responseText));
  32. }
  33. xhr.onerror = function(){
  34. reject("获取电影信息失败");
  35. }
  36. xhr.open("GET",url02+id);
  37. xhr.send();
  38. })
  39. }
  40. //3. 获取导演信息
  41. function getDirectorInfo(id){
  42. return new Promise(function(resolve,reject){
  43. let xhr = new XMLHttpRequest();
  44. xhr.onload = function(){
  45. resolve(JSON.parse(xhr.responseText));
  46. }
  47. xhr.onerror = function(){
  48. reject("获取导演信息失败");
  49. }
  50. xhr.open("GET",url03+id);
  51. xhr.send();
  52. })
  53. }
  54. // 1. 排行榜
  55. getTopInfo().then(function(res){
  56. console.log(res);
  57. message += res.subjects[0].title;
  58. return getMovieInfo(res.subjects[0].id);
  59. }
  60. //直接调用第二次异步请求
  61. // ,function(){
  62. // console.log("请求电影排行榜失败");
  63. // }
  64. )
  65. //2. 电影详情
  66. .then(function(res){
  67. message += "导演是:"+res.directors[0].name;
  68. return getDirectorInfo(res.directors[0].id);
  69. })
  70. //3. 获取导演信息
  71. .then(function(res){
  72. message += "家乡是:"+res.born_place;
  73. document.querySelector("#main").innerHTML = message;
  74. },function(msg){
  75. console.log(msg);//只写一个reject函数即可
  76. })
  77. </script>

解答三:Promise更简洁

  1. <body>
  2. <div id="main"></div>
  3. </body>
  4. <script>
  5. //1. 排行榜
  6. let url01 = "http://api.unclealan.cn:4100/movie/top";
  7. //2. 电影详情
  8. let url02 = "http://api.unclealan.cn:4100/movie/subject/";
  9. //3. 电影人详情
  10. let url03 = "http://api.unclealan.cn:4100/movie/celebrity/";
  11. let message = "排行榜第一的电影是:"
  12. //异步获取接口数据
  13. function getInfo(url, errmes, id=0){
  14. //如果传递了id,url拼接id
  15. if(id !==0){
  16. url +=id;
  17. }
  18. return new Promise(function(resolve,reject){
  19. let xhr = new XMLHttpRequest();
  20. xhr.onload = function(){
  21. resolve(JSON.parse(xhr.responseText));
  22. }
  23. xhr.onerror = function(){
  24. reject(errMsg);
  25. }
  26. xhr.open("GET",url);
  27. xhr.send();
  28. })
  29. }
  30. getInfo(url01,"获取电影排行榜失败").then(function(res){
  31. message += res.subjects[0].title;
  32. return getInfo(url02,"获取电影详情失败",res.subjects[0].id);
  33. })
  34. .then(function(res){
  35. message += "导演是:"+res.directors[0].name;
  36. return getInfo(url03,"获取导演信息失败",res.directors[0].id);
  37. })
  38. .then(function(res){
  39. message += "家乡是:"+res.born_place;
  40. document.querySelector("#main").innerHTML = message;
  41. },function(msg){
  42. console.log(msg);
  43. })
  44. </script>

4. Promise方法

(1)then()

(2)catch()参数一个回调函数,promise状态为reject时调用,代替then中失败参数

例子:

  1. <script>
  2. function timeout(){
  3. let randNum = Math.random() * 2;
  4. console.log(randNum);
  5. return new Promise(function(resolve,reject){
  6. if(randNum > 1){
  7. resolve();
  8. }else{
  9. reject();
  10. }
  11. })
  12. }
  13. timeout().then(function(){
  14. console.log("成功");
  15. })
  16. .catch(function(){
  17. console.log("失败");
  18. })
  19. </script>

(3)all() 参数是数组,数组成员都是多个Promise对象

  1. <script>
  2. function timeout01(){
  3. let randNum = Math.floor(Math.random() * 10);//0-9随机整数
  4. return new Promise(function(resolve,reject){
  5. setTimeout(function(){
  6. if(randNum > 5){
  7. resolve(randNum);
  8. }else{
  9. reject("timeout01失败");
  10. }
  11. },1000)
  12. })
  13. }
  14. function timeout02(){
  15. let randNum = Math.floor(Math.random() * 10)+10;//10-19随机整数
  16. return new Promise(function(resolve,reject){
  17. setTimeout(function(){
  18. if(randNum > 15){
  19. resolve(randNum);
  20. }else{
  21. reject("timeout02失败");
  22. }
  23. },2000)
  24. })
  25. }
  26. function timeout03(){
  27. let randNum = Math.floor(Math.random() * 10)+20;//20-29随机整数
  28. return new Promise(function(resolve,reject){
  29. setTimeout(function(){
  30. if(randNum > 25){
  31. resolve(randNum);
  32. }else{
  33. reject("timeout03失败");
  34. }
  35. },3000)
  36. })
  37. }
  38. Promise.all([timeout01(), timeout02(), timeout03()]).then(function(res){
  39. console.log(res);//Array [ 6, 18, 29 ]
  40. })
  41. .catch(function(res){
  42. console.log(res);
  43. })
  44. </script>

(4) race() 参数是数组,数组成员都是Promise对象,输出最先完成的异步操作

例子一:

  1. <script>
  2. function loadImage(){
  3. return new Promise(function(resolve,reject){
  4. let img = new Image();
  5. img.src = "http://c.hiphotos.baidu.com/image/pic/item/0824ab18972bd407cf293db177899e510eb30994.jpg";
  6. img.onload =function(){
  7. resolve(img);
  8. }
  9. img.onerror = function(){
  10. reject("图片加载失败");
  11. }
  12. })
  13. }
  14. function timeout(){
  15. return new Promise(function(resolve,reject){
  16. setTimeout(function(){
  17. reject("图片请求失败");
  18. },6000)
  19. })
  20. }
  21. Promise.race([loadImage(), timeout()]).then(function(res){
  22. document.body.appendChild(res);
  23. })
  24. .catch(function(res){
  25. console.log(res);//如果没用图片,直接输出timeout中“图片请求失败”
  26. })
  27. </script>

all()和race()区别:

all()所有的Promise对象状态改变,才执行then;

race()执行最快的Promise,最快的Promise状态改变,其他Promise停止

5. JQuery中使用Promise

  1. <script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
  2. <body>
  3. <div id="main"></div>
  4. <script>
  5. //查找排行榜第一的电影的导演的家乡在哪
  6. //1. 排行榜
  7. let url01 = "http://api.unclealan.cn:4100/movie/top";
  8. //2. 电影详情
  9. let url02 = "http://api.unclealan.cn:4100/movie/subject/";
  10. //3. 电影人详情
  11. let url03 = "http://api.unclealan.cn:4100/movie/celebrity/";
  12. let message = "排行榜第一是:"
  13. // 1. 排行榜
  14. $.ajax({
  15. url: url01,
  16. dataType: "json"
  17. }).then(function(res){
  18. message += res.subjects[0].title;
  19. return $.ajax({
  20. //2. 电影详情
  21. url: url02+res.subjects[0].id,
  22. dataType: "json"
  23. }).then(function(res){
  24. message += ";导演是:"+res.directors[0].name;
  25. return $.ajax({
  26. //3. 电影人详情
  27. url: url03+res.directors[0].id,
  28. dataType: "json"
  29. })
  30. }).then(function(res){
  31. message += ";导演的家乡是:"+res.born_place;
  32. document.querySelector("#main").innerHTML = message;
  33. }).catch(function(){
  34. console.log("请求失败");
  35. })
  36. })
  37. </script>

发表评论

表情:
评论列表 (有 0 条评论,374人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ES6 Promise

    Promise基本上是面试面试必问点之一。为什么能在面试这么高频的呢? 什么是Promise 它的出现是为了更好地解决JavaScript中异步编程的问题,传统的异步编

    相关 ES6 Promise

    Promise promise对象从语法上来看呢,是一个构造函数,用来生成Promise实例,用来封装异步操作,并提供成功后或失败后的结果 所谓Promise,简单说

    相关 ES6 Promise

    promise是一种解决异步函数传递数据问题 回调函数解决---->回调地狱 .Promise Promise是一个对象, 使用时需要创建这个对象 new P

    相关 es6 Promise

    传统实现异步操作就是采用回调函数,回调函数方式本身没有什么问题,但是在多重回调层层嵌套的情况下,那么代码的可阅读性就会出现问题。 Promise对象是一个新的异步操作解决方

    相关 ES6-Promise

    Promise what? 在我看来Promise就相当于一个承诺容器,将所要执行的事件存贮在promise容器中。 Promise在ES6中被统一规范,由浏览