promise是一种异步编码的解决方案,我们最开始的需求是这个样子的。
我们利用ajax去请求一些数据
$.ajax('url1',function(data1) {
// 做一些数据处理,碰到第二个需要网络请求的地方
$.ajax('url2',function(data2) {
// 做一些数据处理,碰到第三个需要网络请求的地方
$.ajax('url3',function(data3) {
// 做一些数据处理,碰到第四个需要网络请求的地方
$.ajax('url1',function(data1) {
...
})
})
})
})
这种就是回调地狱,我们处理的时候非常的麻烦,这个时候就轮到Promise出场了。
Promise的基本使用方式是
new Promise((reject,resolve) => {
resolve();
reject();
});
如你所见,resolve()和reject()都是函数,两者作为参数传入了箭头函数中来初始化Promise对象,
所以后来遇到类似的多个请求的时候使用Promise处理就比较简单,因为Promise把异步的过程和返回数据的处理分开,并且采用链式编程,大大简化了我们的代码。
new Promise((resolve, reject) => {
// 做一些异步请求的处理,如果返回成功
resolve(data);
// 如果返回失败
reject(data);
}).then(data => {
}).catch(data => {
})
补充:Promise的三种状态,pending:等待状态,fulfilled:成功,rejected失败
现在有了Promise之后如何处理刚刚的回调地狱的东西呢?
第一版代码
new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 1000)
}).then((data) => {
console.log(data);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data + 456)
}, 1000);
})
}).then((data) => {
console.log(data);
return new Promise(( reject,resolve) => {
setTimeout(() => {
resolve(data + 789)
}, 1000);
})
}).catch((err) => {
console.log(err);
})
其中我们看到,我们利用setTimeout模拟异步操作,同时用console.log模拟对于数据的处理,同时进行新的请求。
在这个地方要注意一下,我尝试将resolve和reject换了位置,调用了一下发现这个和名字没什么关系,第二个位置就是失败的调用,尽管名字时resolve。
其实对于resolve函数是可以进行简写的。
比如我们的代码
new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 1000)
}).then((data) => {
console.log(data);
return new Promise((resolve, reject) => {
// 中间没有多余的异步请求
resolve(data + 456)
})
})
可以简写为
new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 1000)
}).then((data) => {
console.log(data);
return Promise.resolve(data+'111')
})
再进行简化
new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 1000)
}).then((data) => {
console.log(data);
return data + '111';
})