当前位置: 首页 > news >正文

aspcms中引文 网站修改配置/网络培训心得体会

aspcms中引文 网站修改配置,网络培训心得体会,夸克怎么切换成人模式,普陀微信网站建设传统的异步回调编程最大的缺陷是:回调地狱,由于业务逻辑非常复杂,代码串行请求好几层;并行请求以前也要通过引用step、async库实现。现在ES6推出了Promise,通过Promise的链式调用可以解决回调地狱问题,通过Promise.all…

传统的异步回调编程最大的缺陷是:回调地狱,由于业务逻辑非常复杂,代码串行请求好几层;并行请求以前也要通过引用step、async库实现。现在ES6推出了Promise,通过Promise的链式调用可以解决回调地狱问题,通过Promise.all方法可以解决并行请求的问题。现在我们通过手写Promise来彻底理解Promise的原理。

一、构造简单Promise函数,实现Promise的then方法

先来看一下简单的使用方法:

var promise=new Promise(function(resolved,rejected){console.log(1);resolved('123');
})
promise.then(function(data){console.log('success'+data)
},function(err){console.log('fail'+err)
})
复制代码

注意点:

  1. new Promise传入的executor方法代码是同步执行的;
  2. promise对象的状态有三种:pending(等待态),resolved(成功态),rejected(失败态),只能从等待态转化成成功态或失败态;
  3. executor中执行resolve()方法,表示将转化为成功态,promise.then调用时执行成功的方法,executor中执行reject()方法,表示将转化为成功态,promise.then调用时执行失败的方法。

思路:

  1. 首先构造一个类Promise,传入一个参数executor方法;
  2. 用status记录Promise状态,默认是pending,成功态是resolved,失败态是rejected, execuotor执行时,重写resolve、reject方法,执行到这两个方法时,将promise状态修改,并将参数存储起来,以便then方法调用; 3.当实例执行then方法时,依据promise状态来执行成功方法或失败方法。

这样就实现了这个简单的peomise,代码如下:

function Promise(executor){let self=this;self.status='pending';self.value=undefined;self.reason=undefined;function resolve(value){if(self.status==='pending'){self.value=value;self.status='resolved';}}function reject(reason){if(self.status==='pending'){self.reason=reason;self.status='rejected';}}try{executor(resolve,reject)  //第一步:先执行executor,根据里面resolve和reject的调用,执行上面的resolve和reject方法}catch(e){reject(e);}
}
Promise.prototype.then=function(onFulfilled,onRejected){let self=this;//第二步:then被调用的时候根据已经记录的promise状态,执行成功方法或失败方法if(self.status==='resolved'){onFulfilled(self.value);}if(self.status==='rejected'){onRejected(self.reason);}
}
module.exports = Promise
复制代码

二、实现Promise executor中的异步调用

先来看一下简单使用小例子:

var promise=new Promise(function(resolve,reject){console.log('hello')setTimeout(function(){resolve('ok')},1000);
})
promise.then(function(data){console.log('success'+data)
},function(err){console.log('fail'+err)
})
复制代码

上面例子,先打印出hello,过1秒后执行resolve方法,打印出successok。

注意点:

  1. executor执行一秒之后再调用resolve方法,才会执行then中的成功方法;

思路:

  1. executor中方法没调用resolve之前,Promise方法一直是pending状态,这时候执行器已经执行完了then方法,这时我们把then方法中的成功方法和失败方法存入数组,当resolve方法调用时,去执行这些存储起来的方法;
  2. 没有异步调用的话,executor执行时执行resolve方法,成功数组 为空,所以不会被影响,还是在then方法中去执行成功或失败方法。
function Promise(executor){let self=this;self.status='pending';self.value=undefined;self.reason=undefined;self.onResolvedCallbacks=[];self.onRejectedCallbacks=[];function resolve(value){if(self.status==='pending'){self.value=value;self.status='resolved';self.onResolvedCallbacks.forEach(item=>item());//最终执行resolve方法时,修改状态,将成功数组中的方法取出,一一执行。}}function reject(reason){if(self.status==='pending'){self.reason=reason;self.status='rejected';self.onRejectedCallbacks.forEach(item=>item());//最终执行reject方法时,修改状态,将失败数组中的方法取出,一一执行。}}try{executor(resolve,reject)}catch(e){reject(e);}
}
Promise.prototype.then=function(onFulfilled,onRejected){let self=this;if(self.status==='resolved'){onFulfilled(self.value);}if(self.status==='rejected'){onRejected(self.reason);}if(self.status==='pending'){ //执行then的时候是等待态,就将成功方法存入onResolvedCallbacks数组,将失败方法存入onRejectedCallbacks数组self.onResolvedCallbacks.push(function(){onFulfilled(self.value);});self.onRejectedCallbacks.push(function(){onRejected(self.reason);});}
}
module.exports = Promise
复制代码

三、实现Promise then的链式调用

链式调用是Promise中的核心方法,也是最重要的一个方法,先来看一下链式调用的用法:

let p=new Promise((resolve,reject)=>{console.log(1);setTimeout(function(){resolve('123'); },1000);
})
let p2=p.then((data)=>{console.log(data);return new Promise((resolve,reject)=>{setTimeout(function(){resolve('456');},1000);});
},err=>{console.log(err);throw Error('失败');
}).then((data)=>{console.log('aaa'+data);
},(err)=>{console.log(err);
})
复制代码

上面代码首先打印出executor中的1,1秒之后执行resolve方法执行第一个then中的成功方法,先打印出123,再执行此方法中return的Promise,一秒之后执行下一个then的成功方法,打印出aaa456。

注意点:

  1. 如果then方法返回一个普通值,执行下一个then的成功方法;
  2. 如果抛出一个错误,执行下一个then的失败方法;
  3. then方法中返回一个Promise对象,等待Promise对象执行成功就调用下个then的成功方法,这个Promise调用reject()就执行下一个then的失败方法;

思路:

1.在then方法后之所以可以接着调用then方法,肯定then方法需要返回一个Promise实例;

  1. 在then方法中我们用x去接收成功或失败方法的返回值,当成功或失败方法抛出错误,直接执行reject,调用下一个then的失败方法,专门写了一个方法resolvePromise分析返回值;
  2. resolvePromise方法中传入了四个参数,then中的Promise2,x值;
  3. 如果x与promise相等,报类型错误循环引用;
  4. 当x不是null,是个对象类型或者是个函数类型,并且他的then方法也是函数类型时,我们认为x是一个promise实例,执行x.then()方法;再用resolvePromise方法分析他的成功的返回值;
  5. 如果x不是null不是object或function,我们认为x是一个普通值,执行promise2中的resolve方法;
  6. 如果x.then方法获取失败,调用promise2的reject方法;
  7. 定义一个called为true,当执行过resolve或reject方法后将其变为false,保证resolve和reject方法只执行一次;
  8. 这里面存在两个递归调用,一个是then方法里面return new Promise方法,一个是resolvePromise方法,第一个的递归调用解决了executor中异步调用的问题,第二个递归调用解决了return Promise实例的问题。

代码如下:

function Promise(executor){let self=this;self.status='pending';self.value=undefined;self.reason=undefined;self.onResolvedCallbacks = []; // 存放then成功的回调self.onRejectedCallbacks = []; // 存放then失败的回调function resolve(value){if(self.status==='pending'){  //这里面的self不能用this替代,因为是回调执行的时候不是在类里面所以这里的this不是类函数self.status='resolve';self.value=value;self.onResolvedCallbacks.forEach(item=>{item()})}}function reject(reason){if(self.status==='pending'){self.status='reject';self.reason=reason;self.onRejectedCallbacks.forEach(item=>{item()})}}try{executor(resolve,reject);}catch(e){reject(e);}
}
function resolvePromise(promise2,x,resolve,reject){if(promise2===x){//自己等于自己,报类型错误return reject(new TypeError('循环引用了'));}let called;//控制成功或失败只能调用一次if(x!==null && (typeof x==='object'||typeof x==='function')){   try{let then=x.then;if(typeof then==='function'){then.call(x,function(y){  //y可能还是一个promise,递归解析,直到返回普通值if(called)return;called=true;resolvePromise(promise2,y,resolve,reject)},function(err){if(called)return;called=true;reject(err);});}else{resolve(x);}} catch (e) {if (called) returncalled = true;reject(e);}} else { // 说明是一个普通值resolve(x); }}
Promise.prototype.then=function(onFufilled,onReject){onFufilled=typeof onFufilled==='function'?onFufilled:function(value){return value;}onReject=typeof onReject==='function'?onReject:function(err){throw err;//抛出错误,才会走下个then的失败}let self=this;let promise2;if(self.status=='pending'){promise2=new Promise(function(resolve,reject){self.onResolvedCallbacks.push(function(){setTimeout(function(){try{let x=onFufilled(self.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e)}})});self.onRejectedCallbacks.push(function(){setTimeout(function(){try{let x=onReject(self.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}})});})}if(self.status=='resolve'){promise2=new Promise(function(resolve,reject){setTimeout(function(){try{let x=onFufilled(self.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e)}})})}if(self.status=='reject'){promise2=new Promise(function(resolve,reject){setTimeout(function(){try{let x=onReject(self.reason);//这里的x可能是一个普通值,也可能是一个promise,所以写个方法统一处理。resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}})})}return promise2;
};
复制代码

四、检测一下我们的Promise是否符合Promise A+规范

我们需要先给Promise类增加一个defer方法,其实就是一个语法糖。

Promise.defer = Promise.deferred = function () {let dfd = {};dfd.promise = new Promise(function (resolve, reject) {dfd.resolve = resolve;dfd.reject = reject;});return dfd
}
复制代码

没有上面的语法糖,无法被检测。 下载一个插件npm install -g promises-aplus-tests 在命令行工具中执行命令:npm install -g promises-aplus-tests ./promise.js 即可检验自己的promise写的如何。

五、附赠Promise的all、race、resolve、reject、catch方法

Promise.all=function(promises){//promises是一个promise的数组,同时需要返回一个promisereturn new Promise(function(resolve,reject){let arr=[];    //arr是最终返回值的结果集let i=0;function processData(index,y){arr[index]=y;if(++i===promises.length){resolve(arr);}}for(let i=0;i<promises.length;i++){  //因为then的时候,for循环已经走了,i值就是最大的,所以这里用let,保证每次i都是都是当前值promises[i].then(function(y){processData(i,y);},function(err){reject();})}})
}
Promise.race=function(promises){return new Promise(function(resolve,reject){for(let i=0;i<promises.length;i++){promises[i].then(function(data){resolve(data);},function(err){reject(err);})}})}
Promise.resolve=function(value){return new Promise(function(resolve,reject){resolve(value);})
}
Promise.reject=function(reason){return new Promise(function(resolve,reject){reject(reason);})
}
Promise.prototype.catch = function (callback) {return this.then(null, callback)
}
复制代码

转载于:https://juejin.im/post/5b5e918d6fb9a04f85536422

http://www.lbrq.cn/news/764515.html

相关文章:

  • wordpress 发布软件/seo多久可以学会
  • 贵阳专业网站建设公司哪家好/石家庄市人民政府官网
  • 淄博市住房和城乡建设厅网站/平台关键词排名优化
  • 东莞网站建设上科/商丘seo博客
  • 做期货看那个网站比较专业/赣州seo排名
  • app设计理念怎么写/网站建设网络推广seo
  • 建设网站的技术手段/免费推广平台有哪些
  • 建设银行信用卡网站查询/网络优化公司排名
  • 文章网站后台/西安企业做网站
  • html5开发wap网站/百度网盘客服人工电话
  • 给客户做网站需要提供/安阳企业网站优化外包
  • 网站设计专家/网络优化公司哪家好
  • 怎样靠做网站赚钱吗/下载优化大师安装桌面
  • 做视频网站用什么格式好/网站推广代理
  • 网站建设找谁做/网站优化推广方案
  • 网站建设推广公司哪家权威/如何利用网络广告进行推广
  • 购物网站开发模板/steam交易链接在哪里看
  • 做推广必须知道的网站/注册域名费用一般多少钱
  • 小企业网站建设平台/网站排名优化培训课程
  • 水果零售电子商务网站综合评价与建设研究/推广运营怎么做
  • 做网站要提供什么/推广软件一键发送
  • 企业网站首页设计评价/百度竞价托管靠谱吗
  • 苏州做网站需要多少钱/搜狐财经峰会
  • 宜昌本地网站建设/网络营销公司经营范围
  • 企业做网站上海/营销工具
  • 青岛高端网站开发公司/菏泽seo
  • 微信网站建设热线/网络营销的三种方式
  • 阿里巴巴网站详情页怎么做的/郑州模板网站建设
  • 家庭服务网站的营销策略/常见的网络营销推广方式有哪些
  • 给网站做导流/宁波网站制作优化服务公司
  • [工具]vscode 使用AI 优化代码
  • 读《精益数据分析》:移情(Empathy)—— 验证真实需求,避免伪需求陷阱
  • 从零到一:TCP 回声服务器与客户端的完整实现与原理详解
  • 人工智能入门①:AI基础知识(上)
  • Windows基础概略——第一阶段
  • SQL详细语法教程(一)--数据定义语言(DDL)