在前端开发中,相信很多读者都使用过AJAX,这种比较:ox: 逼的异步处理方式,确实在一定程度上方便和简化了我们的某些需求,但有时候也会遇到在一个操作中,会需要多个异步请求的情况,在以往的处理中,比如笔者就曾做过2个及多个AJAX层层嵌套着处理的方式,这种方式,在当时看上去也可以满足一般的需求,但看着别扭,总觉得哪里不爽;
$.ajax({ cache: false, type: 'POST', url: url1, dataType: 'json', success: function (data) { $.ajax({ cache: false, type: 'POST', url:url2, data: { para: list}, dataType: 'json', success: function(result) { ...... } }) } })
如上,魔鬼嵌套;
很快,随着ES6的发布,Promise横空出世,之前多个AJAX多层嵌套的处理方式,看上去显得那么的low,如此的恶劣不堪,反观Promise,高端大气上档次-------哈哈,是不是有点喜新厌旧的嫌疑啊------瞬间,让我喜欢上了,有点一见钟情的赶脚:laughing:
整个就是一大方优雅的典范啊:
readFile(filename).then(function (data) { return data; }).then(function (data) { return readFile(data); }).then(function (data) { console.log(data); }).catch(function(err){ ...... });
二、原理浅析
-
Promise 名如其实,Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才做,例如网络请求、读取本地文件等;
在这个过程中,Promise会经历三个状态:
- Pending Promise对象实例创建时候的初始状态
- Fulfilled 可以理解为成功的状态
- Rejected 可以理解为失败的状态
then 方法就是用来指定Promise 对象的状态改变时确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)
- 示例分析:
let promise = new Promise((resolve, reject) => { setTimeout(() => { if(Math.random()>0.5) resolve('This is resolve!'); else reject('This is reject!'); }, 1000); }); promise.then(Fulfilled,Rejected)
- 构造一个Promise实例需要给Promise构造函数传入一个函数。
-
传入的函数需要有两个形参,两个形参都是function类型的参数。
- 第一个形参运行后会让Promise实例处于resolve状态,所以我们一般给第一个形参命名为resolve,使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作
- 第一个形参运行后会让Promise实例处于reject状态,所以我们一般给第一个形参命名为reject,将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作
三、小试牛刀
经过一些时间的学习和摸索,笔者在ES6自带的Promise的基础上,实现了对其all、race、resolve、reject的功能模拟;
- Promise.all
- 参数:接受一个数组,数组内都是Promise实例。
- 返回值:返回一个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中所有的实例都处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意一个实例处于reject状态,返回的Promise实例变为reject状态。
- 代码如下
Promise.all = function(promises){ return new Promise(function(resolve,reject){ let done = gen(promises.length,resolve); for(let i=0;i<promises.length;i++){ promises[i].then(function(data){ done(i,data); },reject); } }); }
- Promise.race
- 参数:接受一个数组,数组内都是Promise实例
- 返回值:返回一个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中任何一个实例处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意一个实例处于reject状态,返回的Promise实例变为reject状态。
- 代码如下:
Promise.race = function(promises){ return new Promise(function(resolve,reject){ for(let i=0;i<promises.length;i++){ promises[i].then(resolve,reject); } }); }
- Promise.resolve
- 该方法返回一个Promise实例,这个实例处于resolve状态。 会根据传递的参数不同而有不同的功能:
- 当参数是值(对象、数组、字符串等)类型的:作为resolve传递出去的值;
- 当参数是Promise实例:则原封不动返回;
- 代码如下:
//返回一个立刻成功的promise //但该方法,需要传入一个promise,但你只有一个普通的值,你就可以通过这个方法 //把这个普通的值(string number object)转成一个promise对象 Promise.resolve = function(value){ return new Promise(function(resolve){ resolve(value); }); }
- Promise.reject
- 该方法返回一个Promise实例,这个实例处于reject状态。
- 参数一般就是抛出的错误信息。
- 代码如下:
//返回一个立刻失败的promise Promise.reject = function(reason){ return new Promise(function(resolve,reject){ reject(reason); }); }
四、小结
以上就是在下对前端经常遇到的异步处理方式的前认与后知;本人自知才疏学浅,如果有一些理解的有失偏颇之处,欢迎各位随时拍砖与指正~!
当然,如果对您还有点作用的话,还望您评论鼓励,以资我继续前行,小可不胜感激~!
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。