最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript 中 Promise对象 的部分使用特点

    正文概述 掘金(jzplp)   2021-02-26   522

    回调函数和异步编程是JavaScript的特点之一,但是JavaScript中传统的回调函数编写太麻烦,如果嵌套的回调函数层级过多,容易产生“回调地狱”的现象,代码变得非常难看。因此Promise在ES6被引入用来解决这个问题。

    Promise的基本方法

    const promise1 = new Promise((resolve, reject) => {
      // some thing
      if(/* some */)
        resolve(/* some */)
      else
        reject(/* some */)
    });
    
    promise1.then(v => {
      // resolve函数
      // do some
    }, e => {
      // reject函数
      // do some
    })
    

    JavaScript 中 Promise对象 的部分使用特点

    代码中上面是创建Promise的过程。

    创建Promise时接受一个函数作为参数,这个函数就是作为Promise异步执行的主要函数。

    (resolve, reject) => {
      // some thing
      if(/* some */)
        resolve(/* some */)
      else
        reject(/* some */)
    }
    

    JavaScript 中 Promise对象 的部分使用特点

    执行结束后,执行resolve(成功)或者reject(失败)这两个函数。

    这两个函数就定义在.then的参数中。

    如果Promise没有执行resolve(成功)或者reject(失败),那么.then中的内容永远不会执行,这样就实现了异步操作。

    promise函数的异步特点

    Promise一个很有意思的特点,就是Promise函数中resolve(成功)或者reject(失败)是异步的:

    const promise1 = new Promise((resolve, reject) => {
      reject('fail');
      console.log("promise1");
    });
    
    promise1.then(v => console.log("then1"), e => console.log(e))
    

    JavaScript 中 Promise对象 的部分使用特点

    浏览器执行结果:

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    我们先调用reject,然后此时函数应该跳转到then中的reject函数执行。但是并没有。

    程序先输出了promise1然后再是fail。这说明resolve和reject是异步的,执行到resolve或reject时标记状态,然后继续执行完promise函数再进入then中。

    throw类似reject,但有区别

    throw通常情况下可以看作reject。

    const promise1 = new Promise((resolve, reject) => {
      console.log("promise1");
      reject('fail');
    });
    
    const promise2 = new Promise((resolve, reject) => {
      console.log("promise2");
      throw 'fail';
    });
    
    promise2.then(v => console.log("then1"), e => console.log(e))
    

    JavaScript 中 Promise对象 的部分使用特点

    上面的代码中,promise1和promise2的唯一区别是reject换成了throw,但效果是相同的,reject函数成功捕获了错误,把它当成是一个reject来处理。

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    但throw的一个很大区别是,在promise函数中会同步执行,不会等待promise函数执行完毕再进入then。

    const promise1 = new Promise((resolve, reject) => {
      reject('fail');
      console.log("promise1");
    });
    
    const promise2 = new Promise((resolve, reject) => {
      throw 'fail';
      console.log("promise2");
    });
    
    promise2.then(v => console.log("then1"), e => console.log(e))
    

    JavaScript 中 Promise对象 的部分使用特点

    我们把reject和throw上调了,先抛出错误再输出。

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    这时候promise函数中的console.log就没有机会输出了。

    这是由于考虑到reject和throw的语义是不一样的:

    throw表示函数执行出现了错误,不应该继续执行。

    reject表示执行失败,但是不表示有错误。

    then的链式执行

    const promise1 = new Promise((resolve, reject) => {
      console.log("promise1");
      resolve("ok1");
    });
    
    const promise2 = new Promise((resolve, reject) => {
      resolve('ok2');
      console.log("promise2");
    })
    
    promise1.then(v => {
      console.log("then1")
      return promise2;
    }).then(v => console.log("then2", v), e => console.log("then2", e));
    

    JavaScript 中 Promise对象 的部分使用特点

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    在then中返回另一个Promise,或者抛出错误(throw),后面的then就会接受另一个Promise的状态,调用resolve或者reject。

    此时还可以看到,在创建Promise后,promise函数接已经在执行了,我们在then中返回的promise2时早就执行完毕,仅仅是把resolve或者reject状态传递给了下一个then。

    then中即使不返回另一个Promise,也可以链式执行:

    Promise.resolve(2).then(() => console.log(1)).then(() => console.log(2))
    

    JavaScript 中 Promise对象 的部分使用特点

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    这是因为resolve和reject函数默认返回一个promise。我们看到浏览器每次执行完毕后输出的最后结果就是这个promise。

    (看上面浏览器输出的最后一行)

    注意这个promise并不代表我们一开始建立的promise。

    如果我们指定了返回值,那么相当于返回默认的promise时附带了参数:

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    reject可被省略

    then中的reject函数可以省略:

    const promise1 = new Promise((resolve, reject) => {
      resolve('ok');
      console.log("promise1");
    });
    
    promise1.then(v => console.log("then1"))
    

    JavaScript 中 Promise对象 的部分使用特点

    但是如果此时调用reject也无法被then读取。

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    catch可替代reject

    promise1.then(v => console.log("then1"), e => console.log(e));
    
    promise1.then(v => console.log("then1")).catch(e => console.log(e))
    

    JavaScript 中 Promise对象 的部分使用特点

    这两种形式是相等的。

    reject和catch的链式捕获

    在链式then中,rejcect和catch可以捕获之前任一层出现的错误。

    const promise1 = new Promise((resolve, reject) => {
      throw new Error('fail');
      console.log("promise1");
    });
    
    const promise2 = new Promise((resolve, reject) => {
      resolve('ok');
      console.log("promise2");
    })
    
    promise1.then(v => {
      console.log("then1")
      return promise2;
    }).then(v => console.log("then2", v), e => console.log("then2", e));
    

    JavaScript 中 Promise对象 的部分使用特点

    浏览器执行结果:

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    从结果中我们看到,在链式then中,如果出现了reject或者throw,后面所有then中的resolve都不会被执行。上面then1就没被执行,且promise2虽然是resolve状态,但是依然没有被后面then2中的resolve接受,反而执行了then2的reject。

    改成catch的写法:

    promise1.then(v => {
      console.log("then1")
      return promise2;
    }).then(v => console.log("then2", v)).catch(e => console.log("then2", e));
    

    JavaScript 中 Promise对象 的部分使用特点

    在执行完reject之后,promise就变为了resolve状态。如果后面还有链式then,就可以执行reslove了。

    JavaScript 中 Promise对象 的部分使用特点JavaScript 中 Promise对象 的部分使用特点

    可以看到,在执行完reject之后,后面then中的resolve也被执行了。

    最后,文章中描述的resolve状态,实际上应该是fulfilled(已完成)状态,为了方便理解,我就直接使用了resolve来描述。

    更多资料

    在这里介绍的仅仅是Promise中很少的性质,如果想了解Promise的更多用法,可以看看下面的资料:

    阮一峰 《ES6标准入门》Promise部分

    es6.ruanyifeng.com/#docs/promi…

    MDN文档 Promise部分

    developer.mozilla.org/zh-CN/docs/…

    文章为完全原创,转载请标注来源。


    起源地下载网 » JavaScript 中 Promise对象 的部分使用特点

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元