Promise
博客专区 > _Rui_ 的博客 > 博客详情
Promise
_Rui_ 发表于1个月前
Promise
  • 发表于 1个月前
  • 阅读 5
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

传统回调方式处理异步

异步方法和同步方法混杂

异步同步混杂在一起,使得逻辑复杂,可能会产生恐怖的回调链,回调函数一层层的传递。

如果想多个异步函数的完成后执行一个函数,传统的回调就只能在每次回调异步的时候,检查一次,使得代码十分冗余,不便于阅读。

信任问题

什么是信任问题?如果将回调函数传给异步函数,这样就存在一个控制反转的问题。可能会出现这些问题:例如回调函数调用过早过晚,回调函数被多次调用。

设想你如果想在一个异步操作后回调你提供的函数进行危险操作,现在将这个调用的权利交给这个异步方法,就显得很不合适

promise解决传统回调问题

异步方法和同步方法混杂

promise将所有的同步函数转换成异步函数,使得逻辑统一

信任问题

在每一次promise决议后,tick末尾一定会调用then方法,从而保证then的调用肯定是在promise处理完成后。同时每个promise只能决议一次,也就保证了其then只会执行一次。

Promise的优势

  • 统一异步和同步逻辑,使得逻辑清晰
  • 保证回调的可信任
  • 链式编程使得逻辑清晰

promise的核心概念

  • 每个promise只有三个状态:等待,决议,拒绝。
  • 等待-》决议、等待-》拒绝。只存在着两种转化。而且一但变成决议或则拒绝,就不能再进行修改。
  • 外部不能修改promise的状态,只能promise自己改变状态
  • then()、catch()返回的都是一个全新的决议后的promise,所以使得promise可以链式编程

使用Promise

新建一个Promise

创建一个promise有两种方法,第一种是使用new Promise的方式新建,第二种是使用Promise.resolve()的方式来进行转换

new Promise

构造函数接收一个函数,这个函数有两个变量,第一个变量将完成的结果返回回去,第二个将拒绝的结果返回回去。需要注意的是传入的这个函数是在new的时候立刻执行的。

var promise = new Promise(function(resolve, reject) {
    //传入function的函数会立刻执行
    var value=9;
    console.log("run right away");//1
    if (value){
      resolve(value);
    } else {
      reject(error);
    }
    console.log("finish new promise");//2
  });
  console.log("after new promise");//3
  promise.then(function(value){
      console.log("get value="+value);//5
  })
  console.log("after then");//4

Promise.resolve

其实我认为这个方法并不是真正意义上构造Promise的一个方法,它更多扮演的角色是保护转换,将不是Promise的函数、值、对象装换成一个Promise。为什么会有这样的一个函数,主要在于对Promise的定义。

promise的定义是含有then()方法的对象或者函数,也就是thenable类。除此之外没有其它限制。因此可能将不是Promise的的类放到链式中。

var p={
    then:function(resolve,reject){
        reject("error:this is like a promise");
        resolve("success:this is like a promise");
    }
}
console.log("执行promise.resolve后")
Promise.resolve(p).then(
    function(value){
        console.log(value);
    }
)
Promise.resolve(42);
Promise.resolve(new Promise(function(resolve,reject){}))

注意:Promise.resolve可以接收三种值:Promise,thenable,值

Promise链式

Promise的链式,最大的需要注意的一点就是,一旦决议值就不能发生变化,即使后来有人为这个Promise连上了新的then,但是值依旧是之前的。同时每一个then,catch都是返回新的Promise。

如果完成或则拒绝在then中没有被处理,则原封不动的传递给下一级

p.then(
    function(value){
        console.log(value*2);
        //如果返回的依然是一个异步的,则需要创建一个异步的promise返回回去
        return new Promise(function(resolve,reject){
            setTimeout(function() {
                resolve(value);
            }, 100);
        })
    },
    function(){
        console.log("error");
    }
)
.then(function(value){
    console.log(value*3);
    return Promise.resolve(
        {
            then:function(resolve,reject){
                setTimeout(function() {
                    resolve("the value in the promise:"+value*3);
                }, 100);
            }
        }
    )
})

promise 中的门和闩

  • 所谓的门,就是等待所有promise完成返回后再返回,一旦有拒绝,则返回这个拒绝。Promise.all([p1,p2])
  • 所谓的闩,就是只等待第一个,无论是完成还是拒绝,都以第一个的结果为准。Promise.race([p1,p2]),在超时中使用很多
Promise.race([p,p2])
.then(function fulfilled(value){
    console.log(value);
})
//超时竞赛,一旦超过指定时间则报错
Promise.race([p,timeoutPromise(300)])
.then(
    function fulfilled(value){
        console.log("finish");
    },
    function rejected(value){
        console.log("error:"+value);
    }
)
共有 人打赏支持
粉丝 4
博文 19
码字总数 7421
×
_Rui_
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: