资讯专栏INFORMATION COLUMN

ES6: Promise

roadtogeek / 911人阅读

摘要:换句话说该静态函数返回个处于状态的对象。等价于构造函数的静态函数,创建一个对象并以值作为参数调用句柄函数。等价于介绍构造函数的静态函数,参数是对象组成的可迭代数据集合。

一、概述

ES2015 Promise函数是对PromiseA+标准的实现,并且严格遵守该标准。

二、APIs 2.1 创建Promise对象

Promise构造函数的参数是个包含两个参数的函数,并且该函数的参数分别对应resolve, reject操作(resolve,reject也是函数)。并且只能通过这两个参数改变Promise的状态。

function asynOperation(){
    var promise = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject(1,2,3); // 调用reject操作,并传递reason参数。虽然传递多个参数,但只把第一个作为reson值,符合Promise A+标准
        }, 3000)
    });
    return promise;
    
}
asynOperation().then(function(value){
    console.log("ES2015 Promise: resolved and value is " + value);
}, function(reason){
    console.log("ES2015 Promise: rejected and reason is " + reason);
})

上面的代码用zpotojs实现:

/*
    ZeptoJS Deferred
*/
function AsynOperation1(){
    var deferred = $.Deferred();
    setTimeout(function(){
        deferred.reject(1, 2, 3);
    }, 3000);
    return deferred.promise();
}
AsynOperation1().then(function(val){
    console.log("Fullfilled: " + val);
}, function(reason){
    console.log("Rejected: " + reason);
})
2.2 Promise.prototype.catch

catch方法用来添加Rejected状态回调,是then方法的一种子集。

asynOperation().catch(function(reason){
})
// 等价于
asynOperation().then(undefined, function(reason){
})
2.3 Promise.reject(reason)

Promise构造函数的静态方法,创建个Promise对象并以reason值调用reject句柄函数。换句话说该静态函数返回个处于“Rejected”状态的Promise对象。

var p = Promise.reject(1);
// 等价于
var p = new Promise(function(resolve, reject){
  reject(1);
})
2.4 Promise.resolve(value)

Promise构造函数的静态函数,创建一个Promise对象并以value值作为参数调用resolve句柄函数。换句话说该静态函数返回个处于“fullfilled"状态的Promise对象。

var p = Promise.resolve(1);
// 等价于
var = new Promise(function(resolve){
  resolve(1);
})
2.5 Promise.all(iterable) 2.5.1 介绍

Promise构造函数的静态函数,参数是Promise对象组成的可迭代数据集合。创建个Promise对象,并且参数指定的所以Promise都解决后,该Promise对象该被解决,反之如果其中存在rejected的Promise,则该Promise对象被rejected。
定义个异步操作:

function asynOperation(value, reason){
    var promise = new Promise(function(resolve, reject){
        setTimeout(function(){
            value === undefined ? reject(reason) : resolve(value);
        }, 3000)
    });
    return promise;
    
}

var p1 = asynOperation(1),
    p2 = asynOperation(2),
    p3 = asynOperation(3);
Promise.all([p1, p2, p3]).then(function(value){
    console.log("all resolved: value is " + value); // value是[1, 2, 3] 
})

如果参数元素中发生rejected操作,则立马reject返回的Promise:

var p1 = asynOperation(1),
    p2 = asynOperation(undefined, 2), // reject操作
    p3 = asynOperation(undefined, 3); // reject操作
p2.catch(function(reson){
    console.log("p2")
})
p3.catch(function(reson){
    console.log("p3")
})
Promise.all([p1, p2, p3]).then(function(value){
    console.log("all resolved: value is " + value)
}, function(reason){
    console.log("one rejected: reason is " + reason); // reson值等于发生reject操作的promise对象的reason,即p2
})

显示结果:

2.5.2 对比$.when

Promise.all和$.when很类似。主题功能差不多,参数传递方式不一样:ES2015中把所有的Promise对象的value构建个数组,而$.when是分别传递的。

function AsynOperation1(value, reason){
    var deferred = $.Deferred();
    setTimeout(function(){
        value === undefined ? deferred.reject(reason) : deferred.resolve(value);
    }, 3000);
    return deferred.promise();
}
var p1 = AsynOperation1(1),
    p2 = AsynOperation1(2),
    p3 = AsynOperation1(3);
$.when(p1, p2, p3).then(function(value){
    console.log("resolved " + value); // 留意Value的值
}, function(reason){
    console.log("rejected " + reason);
})
2.6 Promise.race(iterable)

Promise构造函数的静态函数,参数是Promise对象构成的可迭代对象,创建个Promise对象。当参数任意Promise对象fullfilled(rejected)时,则立马fullfill(reject)该Promise对象。

var p1 = asynOperation(1),
    p2 = asynOperation(undefined, 2),
    p3 = asynOperation(undefined, 3);
Promise.race([p1, p2, p3]).then(function(value){
    console.log("one resolved: value is " + value); // Value=1
}, function(reason){
    console.log("one rejected: reason is " + reason)
})
三、micro-task

Promise的回调通过micor-task实现的。

console.log(1)
setTimeout(function(){ console.log(2)}, 0)
Promise.resolve().then(function(){console.log(3)})
console.log(4)
// 输出应该是:1 4 3 2
四、对比Promise A+ 标准

大部分Promise A+标准的实现对"Promise解决过程"标准的实现略有不同,比如zeptoJs Deferred就没考虑thenable情况。但是ES2015 Promise函数完全严格遵守Promise A+标准,包含对“Promise 解决过程的实现。下面举例说明实现Promise解决过程(The Promise Resolution Procedure):[[Resolve]](promise, x)

3.3.1 如果promise对象和x相等,则用TypeError对象作为reason 拒绝promise对象
var p1 = asynOperation(1);
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
        return p2; // 返回p2对象,
    },function(reason){
        console.log("rejected: " + reason);
        }};
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);

var p1 = asynOperation(1);
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
         return asynOperation(2); // 返回个Promise对象,以该Prmoise对象状态决定p2的状态
    },function(reason){
        console.log("rejected: " + reason);
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);
})

3.3.3 如果x是thenable,promise状态的改变取决于x.then方法的执行中resolve,reject句柄的调用情况。并不受x.then返回值的影响。

A:then方法没有调用resolve或者reject,并且没有返回值,则不会改变promose的状态

var p1 = asynOperation(1);
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
        return {name: "john", then: function(resolve, reject){ // 返回值是个thenable对象,但是then方法没有调用resolve或者reject,并且没有返回值
            
        }};
    },function(reason){
        console.log("rejected: " + reason);
        
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);
})

B:then方法中调用resolve句柄,用新value y递归调用Promise解决过程:[[Resolve]](promise, y)

var p1 = asynOperation(1);
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
        return {name: "john", then: function(resolve, reject){
            resolve(2); // then方法中调用resolve句柄,用新value递归调用Promise解决过程
        }};
    },function(reason){
        console.log("rejected: " + reason);
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);
})

C:then方法中调用reject句柄,则用相同的reason拒绝promise.

var p1 = asynOperation(1);
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
        return {name: "john", then: function(resolve, reject){
            reject(2); // 调用reject句柄
        }};
    },function(reason){
        console.log("rejected: " + reason);
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);
})

D:then方法中多次调用resolve, reject句柄,只有第一个调用有效,其他的忽略

E:then方法中抛异常,如果抛异常之前已经调用resolve或者reject句柄,则忽略该异常,反之则以该异常为reason拒绝promise

2.3.4 其他情况,则用x作为value完成promise。
var p1 = asynOperation(undefined, 1); // 拒绝的promise
var p2 = p1.then(function(value){
        console.log("resolved: " + value);
        return {name: "john"};
    },function(reason){
        console.log("rejected: " + reason);
        return 2;
    });
p2.then(function(value){
    console.log("resolved: " + value);
},function(reason){
    console.log("rejected: " + reason);
})
还没结束

一道关于Promise应用的面试题

参考

是时候使用promise了

avaScript Promise迷你书(中文版)

MDN

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93321.html

相关文章

  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    摘要:和和都有和,但是略有不同。实际上返回的是一个对象。和添加的回调,添加的回调。所以在调用成功的情况下执行添加的回调,调用失败时执行添加的回调。,产生对象并,产生对象并,然后继续处理,的语法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不过它们的作用可以简单的用两句话来描述 Deffere...

    Yujiaao 评论0 收藏0
  • es6 - Promise

    摘要:所谓异步编程中的异步是相对于同步的概念的。是一系列异步编程规范的统称。如果中的回调函数返回一个值,那么返回的将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。参考介绍基础篇深入理解与异步编程。 es6 promise与异步编程 对于一些还不具备大量编程经验的朋友来说,promise可能是es6比较难以掌握的点。首先是很多名词,比如Promises,es6 Promise,...

    wemallshop 评论0 收藏0
  • JavaScript 异步

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。写一个符合规范并可配合使用的写一个符合规范并可配合使用的理解的工作原理采用回调函数来处理异步编程。 JavaScript怎么使用循环代替(异步)递归 问题描述 在开发过程中,遇到一个需求:在系统初始化时通过http获取一个第三方服务器端的列表,第三方服务器提供了一个接口,可通过...

    tuniutech 评论0 收藏0
  • 浅谈ES6原生Promise

    摘要:如果有错误,则到的第二个回调函数中,对错误进行处理。假设第一个的第一个回调没有返回一个对象,那么第二个的调用者还是原来的对象,只不过其的值变成了第一个中第一个回调函数的返回值。 ES6标准出炉之前,一个幽灵,回调的幽灵,游荡在JavaScript世界。 正所谓: 世界本没有回调,写的人多了,也就有了})})})})})。 Promise的兴起,是因为异步方法调用中,往往会出现回调函数一...

    yedf 评论0 收藏0
  • ES6Promise:要优雅,也要浪漫

    摘要:就算改变已经发生了,即使再对对象添加回调函数,也会立即得到这个结果。方法接收个参数,第一个参数是状态的回调函数,第二个参数可选是状态的回调函数。简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。 在ECMAScript 6标准中,Promise被正式列为规范,Promise,字面意思就是许诺,承诺,嘿,听着是不是很浪漫的说?我们来探究一下这个浪...

    weizx 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<