个人网站已上线,欢迎来访 https://zihanzy.com
我们知道Promise是JS中进行异步编程的新的解决方案 那么之前没有Promise,我们是如何解决异步编程的? 没错回调函数 如下多个串联的异步操作,不断回调
$(function(){ $.ajax({ url:'1.json', datatype:'json', success:function(one){ $.ajax({ url:'2.json', datatype:'json', success:function(two){ $.ajax({ url:'3.json', datatype:'json', success:function(three){ console.log(one,two,three) } }) } }) } }) })可是回调函数的层级嵌套太深,显得有点麻烦,一直回调==回调地狱
为了解决问题在Es6中产生了一个新特性–Promise,在Promise之前还有Generator的解决方案
Promise的出现大大的减轻了原来的回调地狱,为什么说它是“减轻”因为它还是有回调的存在,不过比之前的回调高明很多
或许别人问Promise解决了什么? 答:解决了原来异步编程的地狱回调 这个答案太普遍了,它不仅解决了地狱回调,而且使指定回调函数的方式更加灵活 先来看一个例子 如下伪代码
//成功回调 function successCallback(res){ console.log('音频文件下载成功'+res) } //失败回调 function failureCallback(error){ console.log('音频文件下载失败'+error) } //下载音频 纯回调的方式 DownloadAudioAsync(music,successCallback,failureCallback)可以看到在使用之前的异步回调方式,我们要在异步任务启动之前就要定义成功与失败的回调函数,这样才能得到函数返回的结果
先指定回调函数—>在启动异步任务 之前的方式我们无法在异步任务启动或者异步任务执行完毕后才指定回调函数
而Promise就解决了这一点
const promise = DownloadAudioAsync(music);//返回promise对象 //第一种 异步任务成功或者失败之前指定回调 promise.then(successCallback,failureCallback) //第二种 异步任务有结果之后指定回调假定异步任务执行花费2秒 setTimeout(()=>{ promise.then(successCallback,failureCallback) },3000)当我们new 一个Promise对象,此时异步任务已经启动执行 可是在异步任务启动时我们根本没有指定回调函数,而是分别在异步任务启动后指定回调函数(此时是在异步任务成功或者失败之前指定的回调函数)
异步任务有结果后指定回调函数
从这里就可以看出Promise的灵活性,我们之前的方式是必须在启动异步任务之前就指定回调函数。
到这里第一个结论就出来了 promise使指定回调函数的方式更加灵活
第二个结论就是我们之前所说的回调地狱 promise支持链式调用,解决了地狱回调问题 如下伪代码
doSomething().then(function(res){ return .. }).then(function(res2){ return ... }).then(function(res3){ console.log('Got the final result:'+res3) }).catch(failureCallback)可以看到使用Promise之后我们在串联异步任务较多时,只需写成功的回调,在最后写失败后的回调,这些异步操作有一个出现问题就会走catch,这里是异步传透的机制。
个人网站已上线,欢迎来访 https://zihanzy.com