Promise 介绍
Promise
是异步编程的一种解决方案。避免了使用回调函数和事件所造成的回调地狱。
Promise
接受两个参数:resolve
和reject
.它们都是函数,被调用时分别会将promise
的状态由pending
改为fulfilled
和rejected
。
Promise
的状态一旦改变,就不会在变。
Promise
对象有三种状态:pending
(进行中),fulfilled
(已成功),rejected
(失败)。
Promise
创建后会立即执行。Promise
会返回一个promise
实例,可以通过then
方法来接受两个回调函数作为参数。第一个回调函数是当Promise
对象的状态变为fulfilled
时调用resolve
,第二个函数时状态变为rejected
调用的reject
。
Promise 基本使用
1 | const ajax = async function (url) {
|
2 | const promise = new Promise(function (resolve, reject) {
|
3 | const xmlHttpRequest = new XMLHttpRequest();
|
4 |
|
5 | const handler = function () {
|
6 | if (this.readyState !== 4) {
|
7 | return;
|
8 | }
|
9 | if (this.status === 200) {
|
10 | return resolve(this.response);
|
11 | } else {
|
12 | return reject(new Error(this.statusText));
|
13 | }
|
14 | }
|
15 |
|
16 | xmlHttpRequest.open('POST', url);
|
17 | xmlHttpRequest.onreadystatechange = handler;
|
18 | xmlHttpRequest.responseType = 'json';
|
19 | xmlHttpRequest.setRequestHeader("Accept", "application/json");
|
20 | xmlHttpRequest.send();
|
21 | });
|
22 | return promise;
|
23 | };
|
24 |
|
25 | ajax('/post/json').then(function (response) {
|
26 | console.log(response);
|
27 | }, function (error) {
|
28 | console.log(error);
|
29 | });
|
ajax
是一个 XMLHttpRequest
对象请求封装。发送POST
请求,返回一个Promise
对象。
then
方法接受两个回调函数,resolve
函数和reject
函数。response
就是ajax
内部的resolve
函数返回的数据。
Promise.prototype.then()
then
方法返回一个新的promise
实例,因此可以用链式调用的方式,在then
方法后面继续调用then
方法。
1 | ajax('/post/json').then(function (data) {
|
2 | return data;
|
3 | }).then(function (data) {
|
4 | console.log(data)
|
5 | });
|
Promise.prototype.catch()
catch
方法用于指定发生错误时的回调函数。
throw
抛出错误和reject
方法的作用是等价的。
1 | const promise1 = new Promise(function (resolve, reject) {
|
2 | reject(new Error('error'));
|
3 | });
|
4 | promise1.catch(function (error) {
|
5 | console.log(error);
|
6 | });
|
7 | const promise2 = new Promise(function (resolve, reject) {
|
8 | throw new Error('error');
|
9 | });
|
10 | promise2.catch(function (error) {
|
11 | console.log(error);
|
12 | });
|
13 |
|
如果promise
的状态已经改变了,那么在抛出错误就是无效的。
1 | const promise = new Promise(function (resolve, reject) {
|
2 | resolve('ok');
|
3 | reject(new Error('error'));
|
4 | });
|
5 | promise.then(function (data) {
|
6 | console.log(data);
|
7 | });
|
8 | promise.catch(function (error) {
|
9 | console.log(error);
|
10 | });
|
Promise与Async/Await
Promise
虽然解决了callback
回调地狱,但是promise
内部的值是无法返回到外面的,
只能通过then
方法来接受处理值。可以通过async/await
来改写。
例如下面的例子,只能通过then
方法获取Promise
内部的值。
1 | async function request(url) {
|
2 | return ajax(url).then(function (response) {
|
3 | return response;
|
4 | }, function (error) {
|
5 | console.log(error);
|
6 | });
|
7 | }
|
8 | request('/post/json').then(data=>console.log(data)).then(data=>console.log(data));
|
通过async/await
改写后:
1 | async function getList(url) {
|
2 | let response = await request(url);
|
3 | console.log(response);
|
4 | }
|
这里await
声明的Promise
异步返回,必须等待有返回值的时候,代码才会继续执行下去。