最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

深入解析ES6中的promise

来源:懂视网 责编:小采 时间:2020-11-27 22:04:21
文档

深入解析ES6中的promise

深入解析ES6中的promise:ES6中的promise对象很早就听说过,据说是为了解决我们使用回调产生回调地狱的问题。今天下午既然有这么想学的欲望,就来看一看吧,当然参考的还是阮一峰老师的教程。 第一部分:什么是Promise 看本文的最后一个例子,迅速理解。 Promise是ES6中的一
推荐度:
导读深入解析ES6中的promise:ES6中的promise对象很早就听说过,据说是为了解决我们使用回调产生回调地狱的问题。今天下午既然有这么想学的欲望,就来看一看吧,当然参考的还是阮一峰老师的教程。 第一部分:什么是Promise 看本文的最后一个例子,迅速理解。 Promise是ES6中的一

即 setTimeout 自身就会先消耗一定的时间。

ok,那么说了半天Promise到底怎么和他们比较呢? 他的价值在哪里呢?

价值都在这里了!看下面的这个例子:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>testsettimeout</title>
</head>
<body>
 <div class="wrap">
 </div>
 <script>
 let promise = new Promise(function(resolve, reject) {
 console.log('Promise! 我是Promise对象里的函数,我最早出现是因为我要给后面一个耗时的家伙提供数据a');
 var a = 20;
 resolve(a);
 });
 promise.then(function(value) {
 console.log('哈哈哈,我得到数据a了,要开始执行喽。我是一个非常耗时的操作,依赖前面的数据,但是我想快一点执行,这有利于用户体验,所以别把我放在后头啊;我被放在了一个新的线程上,不会阻塞别人的');
 for (var i = 0; i < 1000000; i++) {
 var li = document.createElement("li");
 document.querySelector(".wrap").appendChild(li);
 }
 console.log("执行完毕");
 });
 console.log('Hi! 我是什么都不依赖的程序,但我也想快一点执行,不能委屈我啊');
 </script>
</body>
</html>

说明: 在已经执行过的情况下,录制屏幕,然后按下刷新键,可以发现,在new Promise里的函数是立即执行的,紧接着是promise.then()之后的函数立即执行,而没有等待then()函数,最后进入then()函数,说了一堆废话,最后大约2 ~ 3s之后执行结束。故promise.then()函数才是真正的异步执行。

promise实现:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>promise</title>
</head>
<body>
 <script>
 function Mypromise(fn) {
 this.state = 'pending';
 this.value = void 0;
 this.doneList = [];
 this.failList = [];
 // 在创建一个promise的时候,需要传递一个fn函数,接受参数resolve和reject。 
 // resolve和reject目前还没有定义,因为用户是直接调用的,如resolve('success'),所以这个resolve方法是需要我们自己来定义的。
 var self = this;
 function resolve(value) {
 // 一旦resolve,状态机的状态由pending -> resolved
 // 并且在resolve的时候状态必须是pending,才能转换状态。
 // 异步执行所有回调函数
 setTimeout(function () {
 if (self.state == 'pending') {
 self.state = 'resolved'
 self.value = value;
 // 一旦成功,我们就可以执行所有promise上挂载的 doneList 中所有的回调函数了,并将value值传递过去
 for (var i = 0; i < self.doneList.length; i++) {
 self.doneList[i](value);
 }
 }
 }, 0);
 }
 function reject(reason) {
 // 一旦reject,状态机的状态由pending -> rejected
 // 在reject的时候状态必须是pending,才能转化状态。
 // 异步执行所有回调函数
 setTimeout(function () {
 if (self.state == 'pending') {
 self.state = 'rejected'
 self.value = reason;
 // 一旦失败,我么就可以把所有的 failList 调用了,并且传递 reason
 for (var i = 0; i < self.failList.length; i++) {
 self.failList[i](reason);
 }
 }
 }, 0);
 }
 fn(resolve, reject);
 }
 Mypromise.prototype = {
 constructor: Mypromise,
 // then方法接受成功时的回调和失败时的回调
 // 实际上,这里的then方法就像路由中的注册路由一样,是一个注册的过程,而没有真正的调用。
 // 并且then是支持链式调用的,所以then应该返回一个promise。 如果返回旧的,那么因为状态不能改变,所以没有意义,所以我么一定要返回一个新的promise,这样这个状态机才可以再次正常的工作。
 then: function (onResolved, onRejected) {
 var self = this;
 // 对于then而言,最终要返回一个新的promise,这样才支持链式调用。
 var promise2;
 // 这里要做一个判断,看传递进来的是否是一个函数,如果是,则不变,如果不是,就拒绝。
 // 如果是promise.then().then().then(function (value) {}); 我们还希望拿到value,那么就要把value在即使没有用到onResolved的时候也传递下去。对于reason也是如此。
 onResolved = typeof onResolved == 'function' ? onResolved : function (value) {return value;}
 onRejected = typeof onRejected == 'function' ? onRejected : function (reason) { return reason;}
 // 下面这一部分是比较核心的内容,因为then最终要返回一个promise,但是,这个promise究竟应该怎么返回呢? 如果在then中,用户就返回了promise,那么我们就用户的,如果用户用的不是promise,那么我么就要自己封装好这个promise了。 
 // 注意: promise也是需要异步调用的,所以可以使用promise进行封装。
 switch(this.state) {
 case 'resolved': 
 // 如果resolved,则返回一个新的promise
 return promise2 = new Mypromise(function (resolve, reject) {
 setTimeout(function () {
 try {
 // 这里相当于直接就给执行了,看看返回的是什么值,如果是promise,那么直接就使用这个promise了。 
 var x = onResolved(self.value);
 if (x instanceof Mypromise) {
 x.then(resolve, reject);
 }
 } catch (e) {
 reject(e);
 }
 }, 0)
 })
 case 'rejected': 
 // 如果rejected,同样也需要返回一个新的promise
 return promise2 = new Mypromise( function (resolve, reject) {
 setTimeout(function () {
 try {
 var x = onRejected(self.value);
 if (x instanceof Mypromise) {
 x.then(resolve, reject);
 } 
 } catch (e) {
 reject(e);
 }
 }, 0);
 })
 // 如果是pending状态,我们就不能确定使用什么,等到状态确定之后才能决定。 
 case 'pending': 
 return promise2 = new Mypromise(function () {
 // 注意:一般then都是执行的这里, 即在then的时候进行注册,把相应的成功的和失败的都会初测在这里,push的是一个函数,所以这里的onResolved还是没有执行的。
 setTimeout(function () {
 self.doneList.push(function (value) {
 try {
 var x = onResolved(self.value)
 if (x instanceof Mypromise) {
 x.then(resolve, reject)
 } else {
 onResolved(value);
 }
 } catch (e) {
 reject(e)
 }
 });
 console.log(self.doneList)
 self.failList.push(function (value) {
 try {
 var x = onRejected(self.data);
 if (x instanceof Mypromise) {
 x.then(resolve, reject);
 }
 } catch (e) {
 }
 });
 }, 0);
 })
 default: 
 console.log(this.state);
 return;
 }
 }, 
 catch: function (onRejected) {
 return this.then(null, onRejected);
 }
 }
 var promise = new Mypromise(function (resolve, reject) {
 if (5 > 3) {
 resolve('success');
 }
 });
 promise.then(function (value) {
 console.log('哈哈哈哈或');
 });
 </script>
</body>
</html>

总结

以上所述是小编给大家介绍的ES6中的promise,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

文档

深入解析ES6中的promise

深入解析ES6中的promise:ES6中的promise对象很早就听说过,据说是为了解决我们使用回调产生回调地狱的问题。今天下午既然有这么想学的欲望,就来看一看吧,当然参考的还是阮一峰老师的教程。 第一部分:什么是Promise 看本文的最后一个例子,迅速理解。 Promise是ES6中的一
推荐度:
标签: promise ES6 深入
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top