含义
状态
promise 对象代表一个异步操作,有三种状态:
- Pending 进行中
- Resolved 已完成 (又称Fulfilled)
- Rejected 失败
特点
一旦状态改变就不会在改变。
目的
解决回调写法的混乱以及一个统一标准。
以下文字至“用法”前来源于 原文连接
假设有一个数据库保存操作,一次请求需要在三个表中保存三次数据。那么我们的代码就跟上面的代码相似了。这时候假设在第二个db.save出了问题怎么办?基于这个考虑,我们又需要在每一层回调中使用类似try…catch这样的逻辑。这个就是万恶的来源,也是node刚开始广为诟病的一点。
1 | db.save(data, function(data){ |
另外一个缺点就是,假设我们的三次保存之间并没有前后依赖关系,我们仍然需要等待前面的函数执行完毕, 才能执行下一步,而无法三个保存并行,之后返回一个三个保存过后需要的结果。(或者说实现起来需要技巧)
所以解决这个问题的库如 Q 等就出现了,直到 ES6 统一了标准。
用法
1 | var promise = new Promise(function(resolve,reject){ |
Promise 构造函数接受一个一名函数作为参数,这个函数有两个参数,分别为 reslove 和 reject。
- resolve 作用是将promise对象由未完成变为成功。
- reject 作用是将promise对象由未完成变成失败
Promise实例生成后可以使用 then 方法分别给 Resolve 和 Rejected 指定回调函数
1 | promise.then(function(value){ |
例子
1 | funtion timeout(ms){ |
上述代码timeout函数返回一个 Promise 实例,表示1秒后的结果,当运行指定函数手, Promise 实例状态变为resolved 此时就会触发 then 方法绑定的回调函数。
promise的
then方法依然会返回一个Promise实例(不等于原来那个),所以就能再用下一个then来处理。
Promise 数据流动
引用内容同上
第一个then中的两个回调函数决定第一个then返回的是一个什么样的Promise对象。
假设第一个
then的第一个回调没有返回一个Promise对象,那么第二个then的调用者还是原来的Promise对象,只不过其resolve的值变成了第一个then中第一个回调函数的返回值。假设第一个
then的第一个回调函数返回了一个Promise对象,那么第二个then的调用者变成了这个新的Promise对象,第二个then等待这个新的Promise对象resolve或者reject之后执行回调。
1 | getJSON("/post.json").then(function(json){ |
上面代码使用then方法依次制订了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数传入第二个回调函数。
采用链式then 可以指定一组按照次序调用的回调函数,这时候,前一个回调函数可能返回的还是一个Promise对象(即有异步操作),而后一个回调函数就会等待该Promise对象的状态发生变化时候在被调用。如下:
1 | return json.post; |
上面代码中,第一个then方法指定的回调函数返回的是另一个Promise 对象。这时候,第二个then方法指定的回调函数就会等待这个新的Promise对象状态发生变化。若变为 resolve 则会调用 pA 函数。若变为rejected 则会调用 pB 函数。
在这个“链条”上遇到的错误将一直向后
reject。直到有处理为止。
## Promise.prototype.catch()
此方法接受一个回调函数来处理错误。即是 .then(null,rehection) 的别名。
Promise.all()
此方法将多个Promise 实例包装成一个新的实例。并非 Promise.prototype.all
var p = Promise.all([p1,p2,p3])
上述代码中,Promise.all 接受一个数组作为参数,数组每项都是一个 Promise 的实例,若不是就会调用 Promise.resolve方法将其转为 Promise 实例。
- 只有 p1,p2,p3 状态都变成
resolved,p的状态才会变成resolved,此时 p1,p2,p3 的返回值会组成一个数组传递给 p 的回调函数。 - 只要 p1,p2,p3 状态变成
rejected,p的状态就会变成rejected第一个被rejected的实例返回值会传递给 p 的回调函数。
Promise.race()
Promise.race 方法同样是将多个 Promise实例包装成一个新的 Promise 实例。
var p = Promise.race([p1,p2,p3]);
上面代码中,只要p1,p2,p3 中任何一个实例状态改变,p 的状态就是跟着改变,最先改变的实例将会传递给 p 的回调函数。
Promise.resolve()
将现有对象转换为 Promise 对象。
Promise.reject()
此方法放回一个新的 Promise 实例,状态为 Rejected 。