Promise

作者: Powen | 来源:发表于2017-06-13 16:52 被阅读0次

    es6中有个特别的对象Promise,今天我们就来学习它,了解它。

    Promise含义

    Promise 是异步编程的一种解决方案,过往遇到异步编程的时候都是采用回调函数或者事件的形式,它的出现让异步编程更加合理和强大。

    Promise用法

    通过ES6,Promise对象是一个构造函数,用来生成Promise实例
    用最有代表的ajax实现异步。

    var promise = new Promise(function(resolve, reject) {
     // ... some code
             $.ajax({
                  url: url,
                   dataType: 'json',
                   success: function (data) {              
                       resolve(data)
                   },
                  error:function(err){
                       reject()
                    }
               })
    });
    promise.then(function(value) {  
        // success
    }, function(error) {  
        // failure 
    });
    

    这就是基本的用法。

    特点

    • 对象的状态不受外界影响
    • 一旦状态改变,就不会再变,任何时候都可以得到这个结果

    Promise的三种状态

    • pending(进行中)
    • resolved(已完成,又称 Fulfilled)
    • Rejected(已失败)

    在上面Promise构造函数接受一个函数作为参数,这个函数有两个参数,
    resolve()函数是将Promise的状态从“未完成”变为“成功”,并将结果作为参数传递给回调的函数,
    reject()函数是将Promise的状态从“未完成”变为“失败”。
    Promise实例生成以后,then方法分别指定Resolved状态和Reject状态的回调函数。

    例子1:

     var p = new Promise(function (resolve, reject) {   
            setTimeout(function () {
                resolve('owen');
            }, 1000);
        });
        p.then(function(val){
            console.log(val)//一秒后打印owen
        })
    

    例子2:

    var p = new Promise(function (resolve, reject) {   
            setTimeout(function () {
                resolve('owen');
            }, 1000);
        });
        p.then(function(val){
            console.log(val)//一秒后打印owen
            return 'obj'
        }).then(function(str){
            setTimeout(function() {
                console.log(str)//两秒后打印obj
            }, 1000);
        })
    

    我们可以发现,第二个then在第一个then结束后执行,并且接受了第一个then的返回值。
    那结论是:每个then中的回调函数都是接受上一个函数的返回值作为参数传递下去。
    例子3:

    var ajaxPromise = new Promise(function (resolve) {
            resolve(resolve)
        });
        ajaxPromise.then(function () {
            var p = new Promise(function (resolve, reject) {
                $.ajax({
                    url: url,
                    dataType: 'json',
                    success: function (data) {
                        id = data.data[0].id;
                        resolve(id)
                    }
                })
            });
            //返回一个Promise对象
            return p;
        }).then(function (id) {
            console.log(id);
            $.ajax({
                url: url + id,
                dataType: 'json',
                success: function (data) {
                    console.log(data);
                }
            })
        })
    

    这是一种情况后面的回调函数依赖前一个回调函数的某个数据。
    首先创建一个promise实例,立即执行回调,第一个回调执行后获取id,提供个第二个回调使用。由于这里是ajax获取id,属于异步操作,使用return id 第二个回调函数必然拿不到id,所以这里重新创建promise实例,并且返回promise实例。

    Promise.prototype.catch()

    var Promise = new Promise(function (resolve,reject) {
            reject('1')
        });
        Promise.then(function(val){
            console.log(val)
        }).catch(function(err){
            console.log(err)
        })
    

    catch()是指定发生错误时的回调函数。我们调用reject() 使promise状态变改为失败,抛出错误,触发catch()方法,当然then()方法指定的回调如果异步操作抛出错误,一样会触发catch()

    var Promise = new Promise(function (resolve,reject) {
            resolve('1')
        });
        Promise.then(function(val){
            
           throw new Error('errs');
        }).then(function(val){
            console.log(2)
        }).catch(function(err){
            console.log(err)//只会执行这里
        })
    

    注意点:

    var promise = new Promise(function(resolve, reject) {
      resolve('ok');
      throw new Error('test');
    });
    promise
      .then(function(value) { console.log(value) })//只会执行这里   ok
      .catch(function(error) { console.log(error) });
    

    因为当执行resolve()后promise状态已经被改为成功,且不会再被改变。

    Promise.all()

    Promise.all方法接受一个数组(伪数组)作为参数。

    var p1=new Promise(function(resolve,reject){
            $.ajax({
                    url: url,
                    dataType: 'json',
                    success: function (data) {
                        id = data.data[0].id;
                        resolve(id)
                    }
                })
        })
        var p2=new Promise(function(resolve,reject){
            $.ajax({
                    url: url,
                    dataType: 'json',
                    success: function (data) {
                        cid = data.data[0].cid;
                        resolve(cid)
                    }
                })
        })
        var p=Promise.all([p1,p2]).then(function(val){
            console.log(val) //返回一个数组
        })
    

    all()规定参数必须为promise对象。它返回的时间取决于耗时最长操作,且p的状态取决于p1,p2。

    • p1,p2都变为fulfilled时候,p的状态变为fulfilled
    • 只要有一项为rejected,p的状态变为rejected

    试想一下使用场景:某一个操作需要的多个数据来源于其他的多个异步操作,这时我们就可以使用all().

    Promise.race()

    用法跟Promise.all()一样,不同点:

    • p的状态取决于p1,p2 哪个先执行完

    Promise.resolve()

    将现有对象转为Promise对象

    var obj={
        a:1
    }
    var p1=Promise.resolve(obj)
    //等价于
    var p2=new Promise(function(resolve,reject){
        resolve(obj)
    })
    

    相关文章

      网友评论

          本文标题:Promise

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