什么是Promise?
我们用Promise来解决什么问题?Promise 是异步编程的一种解决方案:
从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
1.创建Promise
首先来看看promise的用法,从名字可以看出它是个构造函数,所以我们得new它,得到一个Promise实例p,我们打印p看看
let p = new Promise
console.log(p) // TypeError: Promise resolver undefined is not a function
2.参数
报错信息告诉我们,Promise需要一些参数,这里需要一个函数(我们叫它执行器)作为参数,该函数有两个参数————resolve和reject,这两个参数也是函数(由js引擎提供),我们可以在Promise内部调用,当异步操作成功时,调用resolve,否则reject。
let p =new Promise(function(resolve, reject){
if(/* 异步成功 */){
resolve(data)
}else{
reject(err)
}
})
3.state(状态)
现在我们需要知道一个重要概念,Promise是有“状态”的,分别是pending(等待态)、fulfilled(成功态)、rejected(失败态),pending可以转换为fulfilled或rejected,但fulfilled和rejected不可相互转化。
resolve/reject 方法
resolve方法可以将pending转为fulfilled,reject方法可以将pending转为rejected。
then方法
通过给Promise示例上的then方法传递两个函数作为参数,可以提供改变状态时的回调,第一个函数是成功的回调,第二个则是失败的回调。
p.then(function(data){ // resolve方法会将参数传进成功的回调
console.log(data)
}, function(err){ // reject方法会将失败的信息传进失败的回调
console.log(err)
})
4.链式调用
除此之外,每一个then方法都会返回一个新的Promise实例(不是原来那个),让then方法支持链式调用,并可以通过返回值将参数传递给下一个then
p.then(function(num){
return num
},function(num){
return num
}).then(function(num){
console.log('大于0.5的数字:', num)
},function(num){
console.log('小于等于0.5的数字', num)
})
5.catch方法
catch方法等同于.then(null, reject),可以直接指定失败的回调(支持接收上一个then发生的错误)
6.Promise.all()
这可能是个很有用的方法,它可以统一处理多个Promise
Promise.all能将多个Promise实例包装成一个Promise实例
let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})
let p = Promise.all([Promise1, Promise2, Promise3])
p.then(funciton(){
// 三个都成功则成功
}, function(){
// 只要有失败,则失败
})
这个组合后的Promise实例和普通实例一样,有三种状态,这里有组成它的几个小Promise的状态决定
:
1、当Promise1, Promise2, Promise3的状态都为成功态,则p为成功态;
2、当Promise1, Promise2, Promise3中有任意一个为失败态,则p为失败态;
7.Promise.race()
与all方法类似,也可以讲多个Promise实例包装成一个新的Promise实例
不同的是,all时大Promise的状态由多个小Promise共同决定,而race时由第一个转变状态的小Promise的状态决定,第一个是成功态,则转成功态,第一个失败态,则转失败态
8.Promise.resolve()
可以生成一个成功的Promise
Promise.resolve(‘成功’)等同于new Promise(function(resolve){resolve(‘成功’)})
9.Promise.reject()
可以生成一个失败的Promise
Promise.reject(‘出错了’)等同于new Promise((resolve, reject) => reject(‘出错了’))
想象一个场景,当我们需要发送多个异步请求,而请求之间相互关联相互依赖,没有请求1就不会有请求2,没有请求2就不会有请求3…
这时我们需要这样写
$.get('url', {data: data}, function(result1){
$.get('url', {data: result1}, function(result2){
$.get('url', {data: result2}, function(result3){
$.get('url', {data: result3}, function(result4){
......
$.get('url', {data: resultn}, function(resultn+1){
console.log('成功')
}
}
}
}
});
这样的话,我们就掉入了传说中的回调地狱,万劫不复,不能自拔。
这种代码,难以维护和调试,一旦出现bug,牵一发而动全身。
下面我们看看Promise是如何解决的
// Promise改造ajax,实现,多请求,成功之后拿到所有数据
// 不使用回调地域
function ajax(url){
var p = new Promise(function(s,e){
var xhr = new XMLHttpRequest();
xhr.open("get",url,true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
s(xhr.responseText)
}else if(xhr.readyState == 4 && xhr.status != 200){
e(xhr.status)
}
}
xhr.send();
})
return p;
}
var p1 = ajax("");
var p2 = ajax("");
var p3 = ajax("");
Promise.all([p1,p2,p3]).then(function(res){
console.log(res)
},function(res){
console.log(res)
})
39万+

被折叠的 条评论
为什么被折叠?



