本文共 3219 字,大约阅读时间需要 10 分钟。
Promise是ES6中新增的语法,主要是解决原来回调地狱,也就是回调函数多层嵌套问题。
现在我有两个json文件,分别用ajax来请求,但是要求先请求data.json的数据,然后再请求data1.json的数据。
$.ajax({ url: './data1.json', dataType: 'json', success: function (data) { console.log(data); } }) $.ajax({ url: './data.json', dataType: 'json', success: function (data) { console.log(data); } })
显然,上面的代码是无法保证请求顺序的,你可以不断的刷新来试一试,总是不一样的顺序。
那么,自然而然就想到了回调函数(callback),让请求data1的ajax方法放在回调函数中,等data.json数据请求完毕后再执行。
function callback() { $.ajax({ url: './data1.json', dataType: 'json', success: function (data) { console.log(data); } }) } $.ajax({ url: './data.json', dataType: 'json', success: function (data) { console.log(data); callback(); } })
这样子是可以保证请求顺序的。但是,如果我的需求是请求100个这样的json文件,且要保证顺序,那么我是不是就要在一个回调函数中嵌套另外一个回调函数,再在新的回调函数中再嵌套一个回调函数…
如下图所示,这样就成了回调地狱(callback hell)
为了保证异步函数的执行顺序,不得不使用回调函数嵌套的方法,这样的代码写出来不仅可读性不好,可维护性也很差。试想你愿意修改这样的代码吗?Promise能让我们的代码变得更加优雅。var p2 = new Promise((resolve, reject) => { $.ajax({ url: './data1.json', dataType: 'json', success: function (data) { resolve(data); }, error: (err) => { reject(err); } }) }); var p1 = new Promise((resolve, reject) => { $.ajax({ url: './data.json', dataType: 'json', success: (data) => { resolve(data); }, error: (err) => { reject(err); } }) }); p1 .then((data) => { console.log(data); return p2; //return 一个Promise对象,接收的其实是这个对象的两个形参函数. }, (err) => { console.log('请求失败!', err); }) .then(data => { console.log(data); }, err => { console.log('请求失败!', err); })
当请求成功时,把数据给到resolve函数,失败时把错误给到reject函数。
然后用Promise的实例方法then实现resolve方法和reject方法。在p1中return的值,可以是任意的,但是一般都是一个Promise对象,这样才有意义。虽然返回的是一个Promise对象,但是下一个then方法接收的参数为这个返回的Promise对象中的resolve方法和reject方法。
注意,Promise不是异步的,它只是内部封装了一个异步函数而已。
使用Promise时,通常都会把它封装为一个函数。我们把上面的代码改造一下。
function ajaxPromise(ajaxUrl) { return new Promise((resolve, reject) => { $.ajax({ url: ajaxUrl, dataType: 'json', success: (data) => { resolve(data); }, error: (err) => { reject(err); } }) }) } ajaxPromise('./data.json') .then(data => { console.log(data); return ajaxPromise('./data1.json'); }, err => { console.log('请求失败!', err); }) .then(data => { console.log(data); }, err => { console.log('请求失败!', err); })
这样子的代码,相对于回调函数的层层嵌套,是不是很优雅,很漂亮呢?
转载地址:http://xhozi.baihongyu.com/