ES6语法之Promise

Promise 介绍

Promise 是异步编程的一种解决方案。避免了使用回调函数和事件所造成的回调地狱。

Promise 接受两个参数:resolvereject.它们都是函数,被调用时分别会将promise的状态由pending改为fulfilledrejected

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
// Error: error

如果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异步返回,必须等待有返回值的时候,代码才会继续执行下去。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!