Promise的含义
Promise
是异步编程的一种解决方案,比传统的解决方案 --- 回调函数和事件
---更加合理和强大。
所谓promise
简单说就是个容器,里面保存了某个未来才会结束的事件。(通常是一个异步操作的结果。)
从语法上来说,promise是一个对象,从它可以获取异步操作的消息。
promise对象有以下2个特点:
(1)对象的状态不受外界影响。
promise对象代表一个异步操作,有三种状态。
pending
(进行中),fulfilled
(已成功),和rejected
已失败。
只有异步操作的结果可以决定当前是哪一种状态,其它任何操作都不能改变这个状态。 这也是promise
这个名词的由来。 它的英文原意是承诺
,表示其它手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
promise对象状态的改变有两种可能: 从pending
变为fulfilled
和从pending
变成rejected
。 只要这两种情况发生,状态就凝固了,不会再变了。 会一直保持这个结果。 这时,就称为resolved
(已成型)。
如果改变已经发生,你再对promise对象添加回调函数,也会立即得到这个结果。
这与事件(event)完全不同。 事件的特点是,如果你错过它,再去监听,是得不到结果的。
有了promise对象,就可以将异步操作以同步操作的流程表达出来,避免层层嵌套的回调函数。 此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
基本用法
es6规定,Promise
对象是一个构造函数,用来生成Promise
实例。
下面代码创造了一个Promise
实例。
const promise=new Promise((resolve,reject)=>{
// ... some code
if(/* 异步操作成功 */){
resolve(value)
}else {
reject(error)
}
})
Promise
构造函数接受一个函数作为参数,该函数两个参数分别是resolve
和reject
。 它们是两个函数,由JavaScript引擎提供,不用自己部署。
resolve
函数作用是将Promise
对象状态从未完成
变为成功
(即从pending变为resolved),在异步操作成功时调用,并异步操作的结果作为参数传递出去。
reject
函数作用是,将Promise
对象状态从未完成
变成失败(即从pending变成rejected'),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise
实例生成之后,可以用then
方法方分别指定resolve
状态和rejected
状态回调函数。
promise.then(value=>{
// success的逻辑
},error=>{
// 失败的逻辑
})
then
方法可以接受两个回调函数作为参数。 第一个回调函数是promise
状态变为resolve
时调用,第二个回调函数是Promise
对象变为rejected
时候调用。 其中,第二个参数是可选的。 这两个函数都接受Promise
对象传出的值作为参数。
下面是一个例子:
function timeout(ms){
return new Promise((resolve,reject)=>{
console.log("9989")
setTimeout(function(){
resolve("Andy")
},ms)
})
}
timeout(1000).then(value=>{
console.log(value)
})
console.log("这边先执行")
// 9989
// 这边先执行
// (1秒钟之后出现) Andy
上面代码中,timeout方法返回一个Promise
实例,表示一段时间后才会发生的结果。 过了指定的时间(ms参数)之后,Promise
实例的状态变为resolved
,就会触发then
方法绑定的回调函数。
所以上面代码中,会先打印出 9989,然后打印出"这边先执行",最后所有当前同步任务都执行完毕之后,才会执行then
方法绑定的函数。 然后1秒后控制台打印Andy
Promise新建后就会立即执行。
请看下面的例子:
let promise=new Promise((resolve,reject)=>{
console.log("Promise")
reject("已拒绝")
})
promise.then((value)=>{
console.log(value)
},(value)=>{
console.log(value)
})
// Promise
// 已拒绝
上面new了一个Promise
实例,可以看到这个promise
新建后就执行了。不像传统的函数需要调用才能执行。
上面代码中,首先会执行Promise
里面的 console.log("Promise"),然后执行 reject("已拒绝"),在当前所有同步任务执行完毕之后,调用then()
方法,因为上面是reject
所以调用then
方法中的第二个参数函数,打印出"已拒绝
"
下面是一个用 Promise
对象实现ajax操作的例子。
const getAjax=function(url){
return new Promise((resolve,reject)=>{
const handle=function(){
console.log(this)
if(this.readyState == 4 && this.status==200){
resolve(this.response)
}
if (this.status !==200) {
reject("error")
}
}
const client=new XMLHttpRequest();
client.open("GET",url)
client.onreadystatechange=handle
client.responseType="json"
client.setRequestHeader("Accept","application/json")
client.send()
})
}
getAjax("http://localhost:9098/pz/menu.json").then(res=>{
console.log(res) // {responseCode: 1000, message: "success", content: {…}}
})
网友评论