浅析promise与自定义promise
栏目: JavaScript · 发布时间: 7年前
内容简介:promise的用法简单介绍一下,我觉得如果有人愿意看这篇文章,对promise的用法多多少少也了解;心血来潮,今天去自己试着写了一下promise。先说下我个人对promise的理解1.promise 从表现形式上看,是将执行函数的返回值通过resolve或者reject 抛出data,再在then 函数里面处理data
promise的用法简单介绍一下,我觉得如果有人愿意看这篇文章,对promise的用法多多少少也了解;
new Promise((res, rej) => {
try{
执行函数;
res(data)
} catch(e){
rej(e);
}}).then(resCb, rejCb).then(cb);
心血来潮,今天去自己试着写了一下promise。先说下我个人对promise的理解
1.promise 从表现形式上看,是将执行函数的返回值通过resolve或者reject 抛出data,再在then 函数里面处理data
2.promise 可以链式调用then,上一个then的返回值作为下一个then中函数的实参
但实际上,promise 并非一定是在then 里面执行的,尤其是异步的时候,理应在实例函数中执行,才符合我们对单线程的理解。
promise简单点说分为两部分。 一个是实例化 时候,传入的执行函数 , 另一部分为then中传入的回调函数 这个关系就好比 监考老师 和 学生
如果监考老师 先到了教室,那么自然而然,学生是直接依次进入教室;(实例函数执行较快,超过了then的声明)
如果监考老师 在学生们后面到,那么学生们只能按顺序排队在门口等监考老师;(实例函数执行较慢)
也就是说,执行函数和then函数的声明,先后顺序并非固定(一般情况下then声明先完成)
这个时候就需要一个状态码去判断到底是哪种情况('default', 'resolve' ,'reject')
为了方便理解,可以把resolve 和 reject看成同一类型
我先直接发代码写注释
时间有限,本次先不考虑then 中函数 存在异步的问题
// 简述下逻辑:
//1.定义一个state 是用来判断then 和 实例化时候传入的函数 哪一个先完成
//也就是刚刚说的监考老师和学生的问题。默认值为default, 默认老师没到(实例函数未执行完成)
//2.定义resolve_ 用来存放then 中定义的方法,相当于学生排队的过道,便于按顺序执行,reject_同理,以下不再重复
//3.定义resolveData用来记录抛出值,也就是res(data) 中的data,作为then中方法的参数
//4.在res抛出值的时候,将state改成resolve,相当于表明监考老师到教室了
//如果resolve_队列中已经有定义函数就依次执行它们,相当于如果有学生就进教室。
//5.then 方法声明时候,检测状态state 是不是 default ,如果是,说明还没有抛出值,
//相当于监考老师还没到,学生都去排队,加入到resolve_队列;
//如果状态已经不是default ,那么说明监考老师已经到了,学生不用排队,直接进教室;也就是方法直接执行
new promise_( (res, rej) => res(3)).then(data=> {console.log(data);return 6}).then(data => console.log(data))// 3,6
针对实际例子说一下
上面的例子明显就是 res(3) 先执行完成,然后执行then 的函数
相当于监考老师先到了教室,那么,then 中的定义的函数就应该直接执行
new promise_( (res, rej) => setTimeout( () => res(3), 1000).then(data=> {console.log(data);return 6}).then(data => console.log(data))// 3,6
上面的例子明显就是 then 先定义完成,然后res才抛出值
相当于监考老师后到了教室,那么,then 中的定义的函数就应该默默排队等待
因为 then 和 实例函数 两者顺序并不确定,所以 then 时候要通过state 判断实例函数 是否执行完成,
同时,实例函数执行完成抛出值时,也需要检测一下resolve_队列,判断then 是否已经声明完成。
class promise_ {
constructor(func) {
if(typeof func !== 'function'){
throw Error('实例化中传参必须为函数');
return;
} // 判断下是否传入的是函数 ,与逻辑无关,直接往下看
this.state = 'default'; //用来判断
this.resolve_ = []; // then中reslove 的方法队列,用来接收resolve方法
this.reject_ = []; // then中的reject 的方法队列,用来接收reject方法
this.resolveData = null; // resolve的抛出值
this.rejectData = null; // reject的抛出值
func(this.resolve.bind(this), this.reject.bind(this)); //实例化时候传入的函数
}
then(cb, errCb) {
if(typeof cb !== 'function' || (errCb && typeof cb !== 'function')) {
throw Error('then参数,成功回调函数,失败回调函数');
return;
} // 日常判断是不是传参正确,和逻辑无关
switch(this.state) { // 检测一下监考老师来没来教室
case 'default': this.resolve_.push(cb); this.reject_.push(errCb); break;// 如果监考老师没到场,排队
case 'resolve': this.resolveData = cb(this.resolveData); break; // 如果监考老师到场,直接进来,因为链式调用,所以执行后把抛出值改一下,方便后面的then 用
case 'reject': this.rejectData = errCb(this.rejectData); break;// 如果监考老师到场,直接进来,因为链式调用,所以执行后把抛出值改一下,方便后面的then 用
default: break;
}
return this; // 链式调用
}
resolve(data) {
if(!data) return; // 判断有无参数,和逻辑无关
this.resolveData = data; // 设定抛出值
this.state = 'resolve'; // 将状态设置为resolve ,表示监考老师到场了
while(this.resolve_.length) // 先进先出,依次执行then 中函数
this.resolvedata = this.resolve_.shift()(data);
}
reject(data) {
if(!data) return;
this.rejectData = data;
this.state = 'reject';
while(this.reject_.length)
this.rejectData = this.reject_.shift()(data);
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective JavaScript
David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99
"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!
CSS 压缩/解压工具
在线压缩/解压 CSS 代码
RGB CMYK 转换工具
RGB CMYK 互转工具