• 售前

  • 售后

热门帖子
入门百科

关于javascript中的promise的用法和留意事项(保举)

[复制链接]
极品小处男处v 显示全部楼层 发表于 2021-10-25 19:35:13 |阅读模式 打印 上一主题 下一主题
一、promise描述

promise是javascript中尺度的内置对象,用于表现一个异步操作的最终状态(是失败照旧成功完成)及其结果值。它让你可以或许把异步操作最终成功大概失败的缘故原由和相应的处理步伐相干联,也就是说通过promise你可以自定义异步操作竣事后该做什么。这样的话异步方法就和同步方法很雷同,也有返回值,只不外这个返回值不是立即返回最终的值,而是返回一个promise,当promise的状态发生改变时,就会触发相应的处理步伐。
一个promise无论什么时间都一定处于以下几种状态:1、待定(pending) 2、已兑现(fulfilled) 3、已拒绝(rejected)
promise创建之初是待定状态,它既咩有被兑现也咩有被拒绝,它用于包装还没有被添加promise支持的函数,包装后的函数变成异步操作函数,当操作竣事时,会有两个两个分支,一个是已兑现,一个是已拒绝,如下图。已兑现状态的promise会调用后续的then方法,而已拒绝状态的promise既可以调用then方法,也可以被catch方法捕捉到。为什么then方法可以捕捉两个状态的promise呢?这里先不讲,下面再具体先容。

二、promise 的流程走向

上图是promise的流程图,从左到右可以得知一个promise在待定状态时通过两个分支走向分别进入then方法大概catch方法,这两个c方法都会返回promise,假如这个promise也被敲定了,而且其后也有then方法大概catch方法,则又会进入后续的then和catch中,直至咪有。
也就是说,promise和then大概catch可以形成一个异步操作的链式布局,联合js的事件循环机制,这使得js的上风更加显着,发展至今仍能在浏览器上频仍看到它的身影。
我们要注意流程的特点:
1、promise是对象,它的转移成功不取决于返回值,而取决于状态的敲定(是成功照旧失败)
2、then和catch是函数,只要有promise状态发生了改变,该promise对应背面的then大概catch方法就会被调用,而这两个方法自己会返回一个promise,这个返回的promise又会影响这两个方法背面的then大概catch方法。两个方法的返回值一定是promise。
三、promise的创建
  1. Promise
复制代码
对象是由关键字
  1. new
复制代码
及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”继承两个函数——
  1. resolve
复制代码
  1. reject
复制代码
——作为其参数。当异步任务顺利完成且返回结果值时,会调用
  1. resolve
复制代码
函数;而当异步任务失败且返回失败缘故原由(通常是一个错误对象)时,会调用
  1. reject
复制代码
函数。示比方下:
  1. let myFirstPromise = new Promise(function(resolve, reject){
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function(){
  5.   resolve("成功!"); //代码正常执行!
  6. }, 250);
  7. });
  8. myFirstPromise.then(function(successMessage){
  9. //successMessage的值是上面调用resolve(...)方法传入的值.
  10. //successMessage参数不一定非要是字符串类型,这里只是举个例子
  11. console.log("Yay! " + successMessage);
  12. });
复制代码
四、promise的上风

在promise未出现时,假如我们调用异步代码块的话是没有办法保持次序的,而假如又出现了异步代码结果之间按序的需求,该怎样实现呢?
以前的话通常都会将异步代码一层一层地内嵌来实现异步代码按序实现,但是这就造成了代码维护困难,开辟难度增大
  1. doSomething(function(result) {
  2. doSomethingElse(result, function(newResult) {
  3. doThirdThing(newResult, function(finalResult) {
  4.   console.log('Got the final result: ' + finalResult);
  5. }, failureCallback);
  6. }, failureCallback);
  7. }, failureCallback);
复制代码
这就是经典的回调地狱。而假如使用了前面先容的promise,那么代码就变成了容易维护的链式布局
五、then方法返回的promise类型

当一个
  1. Promise
复制代码
完成(fulfilled)大概失败(rejected)时,返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回。假如
  1. then
复制代码
中的回调函数:
      
  • 返回了一个值,那么
    1. then
    复制代码
    返回的 Promise 将会成为继承状态,并且将返回的值作为继承状态的回调函数的参数值。  
  • 没有返回任何值,那么
    1. then
    复制代码
    返回的 Promise 将会成为继承状态,并且该继承状态的回调函数的参数值为
    1. undefined
    复制代码
    。  
  • 抛出一个错误,那么
    1. then
    复制代码
    返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。  
  • 返回一个已经是继承状态的 Promise,那么
    1. then
    复制代码
    返回的 Promise 也会成为继承状态,并且将谁人 Promise 的继承状态的回调函数的参数值作为该被返回的Promise的继承状态回调函数的参数值。  
  • 返回一个已经是拒绝状态的 Promise,那么
    1. then
    复制代码
    返回的 Promise 也会成为拒绝状态,并且将谁人 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。  
  • 返回一个未定状态(
    1. pending
    复制代码
    )的 Promise,那么
    1. then
    复制代码
    返回 Promise 的状态也是未定的,并且它的终态与谁人 Promise 的终态雷同;同时,它变为终态时调用的回调函数参数与谁人 Promise 变为终态时的回调函数的参数是雷同的。
六、catch捕捉的错误

catch能捕捉promise组合中出现的错误,但是有两种错误不能捕捉:
1、已决议的错误不能捕捉
  1. //创建一个新的 Promise ,且已决议
  2. var p1 = Promise.resolve("calling next");
  3. var p2 = p1.catch(function (reason) {
  4. //这个方法永远不会调用
  5. console.log("catch p1!");
  6. console.log(reason);
  7. });
  8. p2.then(function (value) {
  9. console.log("next promise's onFulfilled"); /* next promise's onFulfilled */
  10. console.log(value); /* calling next */
  11. }, function (reason) {
  12. console.log("next promise's onRejected");
  13. console.log(reason);
  14. });
复制代码
2、异步函数中抛出的错误不能捕捉
需要注意的是,作者亲手实践发现:promise包裹的异步函数实行成功后必须显式地调用resolve和reject方法才气触发后续then和catch方法,假如promise方法包裹的不是异步函数,是普通的同步函数,假如该同步代码运行出错,即便没有调用reject方法时,背面的catch方法仍旧可以或许捕捉到这个错误,但假如同步代码没有出错,没有显式调用resolve方法转移的话,后续的then方法不会触发。
七、高级示例
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. <style>
  8.   *{
  9.    margin: 10px;
  10.   }
  11.   html{
  12.    width: 100%;
  13.    height: 100%;
  14.   }
  15.   body{
  16.    width: 100%;
  17.    height: 100%;
  18.    display:flex;
  19.    align-items: center;
  20.    justify-content: center;
  21.   }
  22.   div.displaydatabox{
  23.    width: 300px;
  24.    height: 300px;
  25.    border-radius: 50px;
  26.    text-align: center;
  27.    line-height: 300px;
  28.    box-shadow: 0 0 10px 2px black;
  29.   }
  30.   div.button{
  31.    width: 100px;
  32.    height: 50px;
  33.    border-radius: 21px;
  34.    border: 2px solid orange;
  35.    line-height: 50px;
  36.    text-align: center;
  37.    cursor: pointer;
  38.   }
  39. </style>
  40. </head>
  41. <body>
  42. <div class="button">创建</div>
  43. <div class="button">输入文字</div>
  44. <div class="button">消失</div>
  45. <script lang="javascript">
  46.   let buttonlist=document.querySelectorAll("div.button");
  47.   let body=document.querySelector("body");
  48.   buttonlist[0].onclick=function()
  49.   {
  50.    let div=document.createElement("div");
  51.    div.className="displaydatabox";
  52.    body.appendChild(div);
  53.   }
  54.   buttonlist[2].onclick=function()
  55.   {
  56.    let div=document.querySelector("div.displaydatabox");
  57.    body.removeChild(div);
  58.   }
  59.   buttonlist[1].onclick=function(e)
  60.   {
  61.    let p1=new Promise((resolve,reject)=>
  62.    {
  63.     setTimeout(()=>{//用setTimeout函数模拟异步函数
  64.      let div=document.querySelector("div.displaydatabox");
  65.      div.textContent="这是promise实验";
  66.      //reject(1);
  67.      resolve(1);//调用resolve将调用第一个then
  68.     },2000);
  69.    }).then(function(resolve){
  70.     return new Promise((resolve,reject)=>{
  71.      console.log("这是状态咩有敲定的promise,所以不会调用后面所有的then方法");            //resolve(1)//没有调用resolve或者reject,所以状态未敲定。如果调用,将输出1和finally it has been called!!
  72.     })
  73.    .then(function(e){
  74.     console.log(e);
  75.    });
  76.    }).catch(function(e)
  77.    {
  78.     console.log(e+" 没有块可以输入!!");
  79.    }).then(()=>
  80.    {
  81.     console.log("finally it has been called!!");
  82.    })
  83.   }
  84. </script>
  85. </body>
  86. </html>
复制代码
到此这篇关于关于javascript中的promise的用法和注意事项的文章就先容到这了,更多相干js中promise用法内容请搜索脚本之家以前的文章或继续浏览下面的相干文章希望各人以后多多支持脚本之家!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作