不想了解过程,请直接划到最后.看最终效果
更多内容欢迎访问个人博客:林除夕javascript
通俗的说就是回调函数嵌套回调函数的问题,以下java
// 声明一个函数 function foo(data, callback) { data++; callback(data); } // 回调地狱 foo(1, function(data) { foo(data, function(data) { foo(data, function(data){ foo(data, function(data){ foo(data, function(data){ foo(data, function(data){ console.log(data);// 7 }) }) }) }) }); });
怎么样是否是很刺激,稍微复杂一点,保证你看到头晕眼花。ajax
将这种嵌套式
的调用改造为串联式
,那么下面咱们就来看看怎么解决.json
其中的关键方法网络
表示一个异步操做: 当实例被建立时就表示一个具体异步操做若是不传入执行函数,那么它只是在形式上是异步操做,可是没有任何的异步实操
以下异步
// 建立一个形式上的异步操做 ===> 没有任何具体的异步操做(例如ajax,jsonp等),咱们知道它是异步操做可是不知道它究竟在操做什么 var p = new Promise(); // 建立一个实际的异步操做 var p = new Promise(function(){ // 在这里执行一个异步操做,例如:ajax请求 })
经过.then指定回调函数(包括成功和失败),以下:函数
// 为了防止咱们的异步操做函数在Promise实例化过程当中被执行,将其封装在一个函数中,在对应的时机去使用它 function sendAjax() { // 建立并返回一个包含实际的异步操做的Promise对象 return new Promise(function(resolve,reject) { // 在这里执行一个异步操做,例如:ajax请求 if('ajax请求出现错误') return reject('错误内容') resolve('成功以后须要用到的数据或内容') }); } // 接收实例对象 var p = sendAjax() // 经过.then方法指定成功和失败的回调 p.then(function(data){ // 默认第一个是成功的回调 }, function(err){ // 默认第二个是失败的回调 })
同执行过程以下: 在异步操做的等待时间内完成后续的处理函数的注册(由于异步操做受网络和数据大小的限制通常时间都较长,然后续注册执行函数由于都是内存内直接操做且数据量很小注册时间几乎能够忽略不计)jsonp
st=>start: 开始 e=>end: 结束 op1=>operation: 调用函数实例化对象 op2=>operation: 发起异步操做请求 op3=>operation: 注册回调函数p.then op4=>operation: 完成异步请求 op5=>operation: 调用回调函数 op6=>operation: 异步请求是否完成 cont=>condition: yes or no? st->op1->op2->op6->cont cont(no)->op3->op5 cont(yes)->op5->e
注意:code
在调用.then的时候,成功的回调(resolve)是必须的,失败的回调(reject)能够不传递
// 为了防止咱们的异步操做函数在Promise实例化过程当中的执行,将其封装在一个函数中 function sendAjax(data) { // 建立并返回一个包含实际的异步操做的Promise对象 return new Promise(function(resolve,reject) { // 在这里执行一个异步操做,例如:ajax请求 if('ajax请求出现错误') return reject('错误内容') resolve('成功以后须要用到的数据或内容') }); } // 接收实例对象 var p = sendAjax(data) // 经过.then方法指定成功和失败的回调 p.then(function(data){ // 默认第一个是成功的回调 }, function(err){ // 默认第二个是失败的回调 }) // ======================== // 串联解决回调地狱问题 sendAjax(data) .then(function(newData1){ // newData就是异步操做获得的数据或内容 // 这里用来放成功以后如何处理 // 数据处理完成后若是还须要执行嵌套的相似操做 return sendAjax(newData2) }) .then(function(newData3){ // newData就是异步操做获得的数据或内容 // 这里用来放成功以后如何处理 // 数据处理完成后若是还须要执行嵌套的相似操做 return sendAjax(newData4) }) .then.... .then(function(result){ // 结束数据嵌套处理,输出数据 console.log(result) })
有两种状况,一种会阻止后续执行,一种不会对象
sendAjax(data) .then(function(newData1){ // newData就是异步操做获得的数据或内容 // 这里用来放成功以后如何处理 // 数据处理完成后若是还须要执行嵌套的相似操做 return sendAjax(newData2) },function(err){ // 在这里执行一个处理失败信息的操做 // 处理完成后返回下一个要处理的对象,这样就不会阻止后续操做 return sendAjax(newData2) }) .then(function(newData3){ // newData就是异步操做获得的数据或内容 // 这里用来放成功以后如何处理 // 数据处理完成后若是还须要执行嵌套的相似操做 return sendAjax(newData4) })
sendAjax(data) .then(function(newData1){ // newData就是异步操做获得的数据或内容 // 这里用来放成功以后如何处理 // 数据处理完成后若是还须要执行嵌套的相似操做 return sendAjax(newData2) }) .then(function(newData3){ ... }) .catch(function(err){ // 输出错误信息 // 这种方式捕获异常和错误,只要前面任何一个.then出现问题都会终止整个执行链,而后抛出异常 })