Stevv's Blog

Do not go gentle into that good night

Promise发送Ajax请求

使用Ajax请求

1.创建一个 XMLHttpRequest 对象
2.初始化, 用get的方式去访问对应API接口
3.发送请求
4.绑定事件,处理响应结果,响应状态码在200-299范围说明成功获取数据,否则返回失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const p = new Promise((resolve, reject) => {
// 2. 执行XHR异步代码,获取省份列表
const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend', () => {
// xhr如何判断响应成功还是失败的?
// 2xx开头的都是成功响应状态码
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()

Promise对象的状态

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:\

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

Promise 优缺点

优点

  • 统一异步API,Promise将逐渐被用作浏览器的异步API,统一现在各种各样的API,以及不兼容的模式和手法。
  • 和事件相比,Promise更适合处理一次性的结果。在结果计算出来之前或之后都可以注册回调函数,都可以拿到正确的值。Promise这个优点很自然。但是,不能使用Promise处理多次触发的事件。链式处理是Promise的又一个优点,但是事件却不能这样链式处理。
  • 解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。
  • Promise带来的额外好处是包含了更好的错误处理方式(包括了异常处理),并且写起来很轻松(因为可以重用一些同步的工具,比如Array.prototype.map())

缺点

  • 无法取消Promise,一旦新建它就会同步执行,无法中途取消。

  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将结束)。

  • Promise真正执行回调的时候,定义Promise那部分实际上已经走完了,所以Promise的报错堆栈上下文不太友好。

Promise发送Ajax请求

resolve 和 reject 都是函数,其中调用 resolve 代表一切正常,reject 是出现异常时所调用的

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
const p = new Promise((resolve, reject) => {
// 2. 执行XHR异步代码,获取省份列表
const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend', () => {
// xhr如何判断响应成功还是失败的?
// 2xx开头的都是成功响应状态码
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})

// 3. 关联成功或失败函数,做后续处理
p.then(result => {
console.log(result)
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error => {
// 错误对象要用console.dir详细打印
console.dir(error)
// 服务器返回错误提示消息,插入到p标签显示
document.querySelector('.my-p').innerHTML = error.message