第六章:Promise的应用

下面是一个Promise的实例

1
2
3
4
5
6
7
8
9
function timeout(ms){
return new Promise((resolve,reject) => {
setTimeout(resolve,ms,'done')
})
}
timeout(100),then((value) => {
console.log(value)
})

上面的代码中,timeout方法返回一个promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为reslove,就会触发then方法绑定的回调函数。

异步加载图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function loadImageAsync(url){
return new Promise(function(reslove,reject){
var image = new Image()
image.onload = function(){
resolve(image)
}
image.onerror = function(){
reject(new Error('could not find image at' + url))
}
image.src = url
})
}

使用Promise实现AjAX操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var getJson = function(url){
var promise = new Promise(function(resolve,reject){
var client = new XMLHttpRequest()
client.open('GET',url)
client.onreadystatechange = handler
client.responseType = 'json'
client.setRequestHeader('Accept','application/json')
client.send()
function handler(){
if(this.readyState !== 4){
return
}
if(this.status == 200){
resolve(this.response)
}else{
reject(new Error(this.statusText))
}
}
})
return promise
}
getJson('/posts.json').then(function(json){
console.log('Contents' + json)
},function(error){
console.Error('出错,error')
})

参数的不确定

如果调用resolve函数和reject时带有参数,那么这些参数挥别传递给回调函数,reject函数的参数通常是Error对象的实例,表示抛出的错误。resolve函数除了正常的值意外,还有可能是另一个promise实例,表示异步操作的结果有可能是一个值,也有可能是另一个异步操作。

1
2
3
4
var p1 = new Promise(function(resolve,reject){})
var p2 = new Promise(function(resolve,reject){
resolve(p1)
})

p1和p2都是promise的实例,但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作

p1的状态改变了p2的状态,如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变,如果p1的状态已经是resolve或reject,那么p2的回调函数将会立即执行。

1
2
3
4
5
6
7
8
9
10
11
12
var p1 = new Promise(function(resolve,reject){
setTimeout(() => reject(new Error('fail')),3000)
})
var p2 = new Promise(function(resolve,reject){
setTimeout(() => resolve(p1),1000)
})
p2.then(result => console.log(result))
p2.catch(error => console.log(result))
//Error:fail

*注意~

  1. p1是一个Promise,三秒之后变为Reject
  2. p2的状态由p1决定,一秒之后,p2调用resolve方法
  3. 此时p1的状态还没有改变,p2的状态也不会变
  4. 两秒之后,p1变为Rejected,p2也跟着变为Rejected