美文网首页
promise分享总结

promise分享总结

作者: 我的天气很好啦 | 来源:发表于2019-03-18 18:04 被阅读0次
    一、promise出现的原因

    在JS的世界中,所有代码都是单线程执行。由于这个缺陷,导致JS的所有网络操作、浏览器事件都必须是异步执行。
    通常异步执行可以采用回调函数的方法来异步执行
    例如

    function callback(){
      console.log('done');
    }
    console.log('before setTimeout()');
    setTimeout(callback, 1000);
    console.log('after setTimeout');
    

    观察上述代码,在chrome的控制台输出可以看到:

    before setTimeout()
    after setTimeout()
    (等待一秒后)
    Done
    

    例如AJAX就是典型的异步操作,例如:

    request.onreadystatechange = function() {
      if(request.readyState === 4){
        if(request.state === 200) {
          return success(request.responseText);
        }else{
          return fail(request.state);
        }
      }
    }
    

    把回调函数success(request.responseText)和fail(request.status)写到一个AJAX操作里很正常,但是不好看,而且不利于代码复用。
    可以换个更好的写法,比如:

    var ajax = ajaxGet('http://...');
    ajax.ifSuccess(success)
          .ifFail(fail);
    

    这种链式写法的好处在于,先统一执行AJAX的逻辑,不关心如何处理结果。然后根据结果的成功还是失败,在将来的某个时候调用success函数或者fail函数。

    二、promise对象的的特点
    • 对象的状态不受外界影响。promise对象代表一个异步操作,有三种状态:pending(进行中)、resolved(已完成)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态。
    • promise对象的状态改变,只有两种可能:从pending变成resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
    三、promise的基本用法

    promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JS引擎提供。

    • resolve函数的作用是,将promise对象的状态从“未成功”变成“成功”,在异步操作成功时调用,并将异步操作的结果作为参数传递出去。
    • reject函数的作用是,将promise对象的状态从“未成功”变成“失败”,在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。
    • then方法可以接受两个回调函数作为参数,第一个回调函数是promise对象的状态变为resolved时调用;第二个回调函数是Promise对象的状态变为rejected时调用。
    resolve(value)和resolve(promise)的区别

    对比背景:我们会在异步操作成功时调用resolve函数,其作用是将promise对象的状态从pending变成resolved,并将异步操作的结果作为参数传递给then()方法里的第一个函数的形参。
    那么传入的参数是值还是promise对象,有什么不同呢?
    举例说明:

            传入的参数是值
            var time = new Date();
            var promise = new Promise(function(resolve, reject) {  
                setTimeout(function() { 
                    console.log("2秒后,我运行了");
                    resolve('异步操作成功了');     
                }, 2000) 
                
            }).then(function (value) {
                console.log(value,new Date() - time);
            })
            //执行的输出结果为:
            //2秒后,我运行了
            //异步操作成功了 2002
    
          传入的参数是promise对象
          var time = new Date();
            var promise = new Promise(function(resolve, reject) {  
                setTimeout(function() { 
                    console.log("2秒后,我运行了");
                    resolve('异步操作成功了');     //1
                }, 2000) 
                
            })
    
            var promise2 = new Promise(function (resolve,reject) {
                setTimeout(resolve,1000,promise);
            }).then(function (value) {
                console.log(value,new Date() - time);
            })
    
            //执行后输出的结果为:
            //2秒后,我运行了
            //异步操作成功了 2003
    

    这里要讨论的是,为什么第二段代码中,promise2设置的执行时间是1秒,为什么还会2秒后打印~
    简单说就是promise2中的resolve()函数传入了promise对象,此时promise对象的状态决定了promise的状态,同时会把返回值传给promise。

    Promise/A+中规定
    2.3.2.如果x是一个promise实例, 则以x的状态作为promise的状态
    2.3.2.1.如果x的状态为pending, 那么promise的状态也为pending, 直到x的状态变化而变化。
    2.3.2.2.如果x的状态为fulfilled, promise的状态也为fulfilled, 并且以x的不可变值作为promise的不可变值。
    2.3.2.3.如果x的状态为rejected, promise的状态也为rejected, 并且以x的不可变原因作为promise的不可变原因。
    2.3.4.如果x不是对象或函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值

    promise与错误状态处理 .catch()方法
    • .then(null, rejection),用于指定异步操作发生错误时执行的回调函数。
    var promise = new Promise(function(resolve, reject){
      setTimeout(function() {
        reject(''error);
      }, 2000)
    }).then(null, function(error) {
        console.log('rejected', error)
      })
    //rejected error
    

    为了捕获异常信息,我们需要为每一个then()方法绑定一个.then(null, rejection)。由于promise对象的错误信息具有“冒泡”性质,错误会一直向后传递,直到被捕获为止。

    • promise原型上有个捕获异常的函数是promise.prototype.catch()
    var promise = new Promise(function(resolve, reject){
      setTimeout(function () {
        reject('error')
      }, 2000)
    }).then(function {
        console.log('resolve', value)
    }).catch(function (error) {
      console.log(error)
    })
    

    上面代码中,一共有两个promise对象,一个由promise产生,一个由then产生,它们之中任何一个抛出的错误,都会被最后一个catch捕获。
    但是如果用.then(null, rejection)方法来处理错误信息,我们需要在每一个rejection()方法中返回上一次异常的信息状态,这样当调用的then()方法一多的时候,就会对代码的清晰和逻辑造成影响。
    所以一般捕获异常用catch方法~

    相关文章

      网友评论

          本文标题:promise分享总结

          本文链接:https://www.haomeiwen.com/subject/jvtpmqtx.html