ES6之Promise

上文中我们提到了如何用预加载来提前获取图片等资源,当我们获取资源的时候常常会有资源获取失败的情况(例如网络不通、资源地址失效、资源地址不正确等),我们可以用try catch来处理这种异常的情况,当然更多的是使用ES6新的Promise对象。在new一个Promise时会传入两个函数,resolve用来处理正常流程,reject是处理异常的方法,最后通过示例化的then方法来启动。我们可以来简单实践一下:

var promise = new Promise(function(resolve,reject){
  var img = new Image();
  img.onload = function(){
    resolve(this); //通过实例的then传进来的correct方法
  }
  img.onerror = function(){
    reject("加载失败"); //通过实例的then传进来的error方法
  }
  img.src = "./image/test.jpg"
})

promise.then(correct(),error()); //通过实例开始处理逻辑

//正常加载调用此方法
function correct(data){
  console.log(data);
}

//加载异常时调用此方法
function error(errorInfo){
  console.log(errorInfo);
}

在这里要注意catch和then的区别是catch会对整个promise做异常捕获,包括resolve。而reject只是对我们已预知的异常,根据具体业务逻辑做的异常处理。

但是这里有个问题要注意,对于promise内部的异步方法,promise.then和promise.catch是捕获不到的,因为回调方法setTimeout会放在异步方法catch和then之后运行。我们可以测试一下。

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    throw "error"; //没有被p.catch捕获到,直接报错
  }, 0);
});

p.catch(err => {
  console.log("catch " + err); // 不会被执行
});

在上面的代码运行结果中并没有正确的打印输出异常,而是报了Uncaught error异常未捕获的错,说明catch捕获异常放在异步函数之前就跑完了。关于异步方法、回调方法、入参方法的运行顺序我们可以通过一个小例子来验证一下。参考https://www.jianshu.com/p/1c829edec185

let a = new Promise(
  function(resolve, reject) {
    console.log(1) //同步方法
    setTimeout(() => console.log(2), 0) //回调方法
    console.log(3) //同步方法
    console.log(4) //同步方法
    resolve(true) //异步方法
  }
)
a.then(v => {
  console.log(8)
})
 
let b = new Promise(
  function() {
    console.log(5) //同步方法
    setTimeout(() => console.log(6), 0) //回调方法
  }
)
 
console.log(7) //同步方法

我们可看到输出结果为1、3、4、5、7、8、2、6。从这里我们发现异步方法优先于回调方法执行。

从这里我们可以总结出,使用promise异步编程时一定要小心与回调方法混合使用,先理清楚再决定调用方法的顺序

参考https://www.jianshu.com/p/1c829edec185

参考https://blog.csdn.net/u010297791/article/details/71158212

 

  

  

posted @ 2019-09-10 23:18  姜小希  阅读(208)  评论(0编辑  收藏  举报