Promise 小记(一)
什么是Promise
只要一提到 JavaScript 异步编程,我想绝大多数人都会想到 JS 回调函数。而 ES6 为我们带来了新的异步编程方式——Promise。
Promise并不是JS首创的,而是来源于E语言,它是基于并列/并行处理设计的一种编程语言。Promise 把基于回调的异步处理对象抽象了出来进行规范化,并采用统一的接口对其进行各种操作。这样,基于Promise的统一接口的做法,可以将复杂的异步处理轻松进行模式化,便于我们的维护和使用。
Promise API
构造实例
Promise 是一个构造函数,需要使用 new 操作符构造出一个新 promise 实例作为接口。对 Promise 实例化时可以传入两个参数分别是 resolve 和 reject。 分别用来设置 promise 实例的异步处理成功还是失败。
let promise = new Promise(function (resolve, reject) {
// 异步处理
// 调用 resolve 或 reject
})
实例方法
promise.then()
构造 promise 实例后,可以使用 then 方法指定 promise 异步处理结果分别为 resolved 状态和 rejected 状态下的回调函数。它接受两个回调函数作为参数,第一个回调将在 Promise 对象状态变为 resolved 时调用,而第二个回调将在 Promise 对象的状态变为 reject 时调用。其中,第二个参数是可选的。这两个回调都接受 Promise 对象传出的值作为参数。
promise.then(onFulfilled, onRejected);
// 只处理resolved
promise.then(onFulfilled);
// 只处理异常
promise.then(undefined, onRejected);
then方法返回的是一个新的 Promise 实例。因此可以采用链式写法,即 then 方法后面再调用另一个 then 方法。
promise
.then(data => JSON.parse(data))
.then(obj => console.log(obj))
promise.catch()
catch 方法是 promise.then(undefined, onRejected);的别名,用于指定发生错误时的回调函数。Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
promise.then(function () {
// 回调
}).then(function () {
// 回调
}).catch(function (err) {
console.log(err);
})
静态方法
Pomise 全局对象还拥有一些静态方法。如Promise.all() Promise.resolve() Primise.race() Promise.reject()。这些方法都是一些针对 Promise 进行辅助操作的方法。就不一一解释。
Promise 工作流
在介绍了 Promise 的 API 后,我们先来开下面一段代码:
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Hello World"), 100);
})
promise
.then(msg => console.log(msg)) // => "Hello World"
.catch(err => console.log(err));
在上面这段代码中,我们用 new 操作符构造了一个 Promise 实例 promise。promise 会在100ms 后被resolved,这时,then 的回调函数会被调用并输出”Hello World”。而由于 promise 执行了 resolve ,因此 catch 回调不会被执行。
我们可以发现, 在 Promise 的整个工作流中, 调用回调是根据 Promise 的状态决定的。
Promise 实例对象有三种状态:
- Pending: 进行中, promise 对象实例化后的初始化状态;
- Resolved(Fulfilled): 已成功,这时会调用
then方法中的第一个回调函数; - Rejected: 失败,这时会调用
then方法中的第二个回调函数或catch的回调。
Promise 的状态从 Pedding 转换为 Resolved 或 Rejected 后,这个 Promise 对象的状态就不再改变。也就是说, Promise 与事件绑定不同,在 then 后执行的函数肯定只会被调用一次。
一个简单的 Promise 应用
下面,我们以一个简单的例子结束这次 Promise 介绍。
我们用 Promise 来处理 XMLHttpRequest 的数据。
const ajax = function (url) {
return new Promise((resolve, reject) => {
let req = new XMLHttpRequest();
req.open("GET", url);
req.onreadystatechange = function () {
if (req.readyState !== 4 ) return;
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.send();
})
}
ajax("http://exmaple.com")
.then(data => console.log(data))
.catch(err => console.error(err));
以上就是一个简单的处理 ajax 的 promise 示例。下次,我将介绍更多 Promise 的使用方法。
