zoukankan      html  css  js  c++  java
  • promise实例的catch方法

    Promise.prototype.catch()

    Promise.prototype.catch()方法是用于指定发生错误时的回调函数

    getJSON('/posts.json').then(function(posts) {
      // ...
    }).catch(function(error) {
      // 处理 getJSON 和 前一个回调函数运行时发生的错误
      console.log('发生错误!', error);
    });

          上边代码中,getJSON( )方法返回一个Promise对象,如果该对象状态为resolved,则会调用then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch( )方法指定的回调函数,处理这个错误。另外,then( )方法指定的回调函数,如果运行中抛出错误,也会被catch( )方法捕获。

    p.then((val) => console.log('fulfilled:', val))
      .catch((err) => console.log('rejected', err));
    // 等同于
    p.then((val) => console.log('fulfilled:', val))
      .then(null, (err) => console.log("rejected:", err));

    下面是一个例子

    const promise = new Promise(function(resolve, reject) {
      throw new Error('test');
    });
    promise.catch(function(error) {
      console.log(error);
    });
    // Error: test

           上边代码中,promise抛出一个错误,就被catch方法指定的回调函数捕获。

    Promise对象的错误具有冒泡的性质,会一直向后传递,直到被捕获为止。

    getJSON('/post/1.json').then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // some code
    }).catch(function(error) {
      // 处理前面三个Promise产生的错误
    });

             上边的代码中,一共有三个Promise对象:一个由getJSON( )产生,两个由then( )产生。它们中,任何一个抛出错误,都会被最后一个catch( )捕获。

    一般来说,不在then()方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。

    // bad
    promise
      .then(function(data) {
        // success
      }, function(err) {
        // error
      });
    
    // good
    promise
      .then(function(data) { //cb
        // success
      })
      .catch(function(err) {
        // error
      });

             上边的代码,第二种写法优于第一种,理由是第二种写法可以捕获前面then方法执行中的错误。因此,建议总是使用catch()方法,而不是使用then( )方法的第二个参数。

    与传统的try/catch代码块不同的是,如果没有使用catch()方法指定错误处理的回调函数,Promise对象抛出的错误不会传递到外层代码,即不会有任何反应,

    const someAsyncThing = function() {
      return new Promise(function(resolve, reject) {
        // 下面一行会报错,因为x没有声明
        resolve(x + 2);
      });
    };
    
    someAsyncThing().then(function() {
      console.log('everything is great');
    });
    
    setTimeout(() => { console.log(123) }, 2000);
    // Uncaught (in promise) ReferenceError: x is not defined
    // 123

          上边的代码中,someAsyncThing( )函数产生的Promise对象,内部有语法错误,浏览器运行到这一行,会打印出错误提示,但是不会退出进程,终止脚本运行,2s之后还是会输出123。 这就是说,Promise内部的错误不会影响到Promise外部的代码,通俗的说法就是“Promise 会吃掉错误

    这个脚本放在服务器执行,退出码是0(即表示执行成功)。不过,Node.js有一个unhandleRejection事件,专门监听未捕获的reject错误,上边的脚本会触发这个事件的监听函数,可以在监听函数里面抛出错误。

    process.on('unhandledRejection', function (err, p) {
      throw err;
    });

          上边的代码中,unhandleRejection事件的监听函数有两个参数,第一个是错误对象,第二个是报错的Promise实例,它可以用来了解发生错误的环境信息。

    注意,Node 有计划在未来废除unhandleRejection事件。如果Promise内部有未捕获的错误,会终止进程,并且进程的退出码不为0.

    一般总是建议,Promise对象后面要跟catch方法,这样可以处理Promise内部发生的错误。catch( )方法返回的还是一个Promise对象,因此后面还可以接着调用then()方法。

    const someAsyncThing = function() {
      return new Promise(function(resolve, reject) {
        // 下面一行会报错,因为x没有声明
        resolve(x + 2);
      });
    };
    
    someAsyncThing()
    .catch(function(error) {
      console.log('oh no', error);
    })
    .then(function() {
      console.log('carry on');
    });
    // oh no [ReferenceError: x is not defined]
    // carry on

         上边的代码运行完catch( )方法指定的回调函数,会接着运行后面那个then()方法指定的回调函数,如果没有报错,则会跳过catch( )方法 

    如下:

    Promise.resolve()
    .catch(function(error) {
      console.log('oh no', error);
    })
    .then(function() {
      console.log('carry on');
    });
    // carry on

          上面的代码因为没有报错,跳过了catch()方法,直接执行后面的then()方法。此时,要是then()方法里面报错,就与前面的catch()无关了。

    catch()方法之中,还能再抛出错误

    someAsyncThing().then(function() {
      return someOtherAsyncThing();
    }).catch(function(error) {
      console.log('oh no', error);
      // 下面一行会报错,因为y没有声明
      y + 2;
    }).catch(function(error) {
      console.log('carry on', error);
    });
    // oh no [ReferenceError: x is not defined]
    // carry on [ReferenceError: y is not defined]

          上面代码中,第二个catch()方法用来捕获前一个catch()方法抛出的错误

  • 相关阅读:
    Opencv3 ——读取图像,显示图像
    QT5生成log日志
    QT5串口读取宇电温控器温度
    QSettings 配置信息写入本地文件
    Qt5应用程序封包
    python 创建虚拟环境
    Ubuntu更换国内源
    一个关于百度编辑器的小问题
    JavaScript等比例缩放图片(转载)
    asp.net io操作,修改文件夹的名称,报错:access to the path is denied
  • 原文地址:https://www.cnblogs.com/zhishiyv/p/14301982.html
Copyright © 2011-2022 走看看