Promise是异步编程的一种解决方案,
比以前用的回调要简单易懂些
它只是一个容器,里面保存着未来发生的事件。
它有三个状态,pending 进行中
resolved 完成
rejected 失败
状态改变将无法再修改。
它是一个构造函数,需要用new来实例化
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
参数函数有两个参数,一个是成功,一个是失败。
函数内可以执行ajax。在回调内调用成功或失败并传递参数。
它在用new创建时函数就已经开始执行了。
可以在函数内输入一行代码,来测试。
但是它的成功或失败的执行是不会执行的。立即ajax已经回调成功了。它只有在调用then时会返回状态。
then会在ajax成功后得到状态的传递值
只有当调用then时才会调用。并传递成功或失败。
promise.then(function(value) {
// success }, function(error) {
// failure });
then有两个函数参数,一个是成功,一个是失败。
一般第二个都不常用。会在最后用catch来处理失败或错误
getJSON("/posts.json").then(function(posts) {
// ... }).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误 console.log('发生错误!', error);
});
状态中返回一个Promise
如resolue(promise)
var p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
var p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000)
})
p2.then(result => console.log(result))
p2.catch(error => console.log(error))
当有两个promise
上面代码中,p1
和p2
都是Promise的实例,但是p2
的resolve
方法将p1
作为参数,即一个异步操作的结果是返回另一个异步操作。
这时P1的状态会传递给p2,而p1最终决定了p2的状态 。
解析:
用在上边代码,就是p13m后返回状态,p2一秒后返回p1
p1 p2同时执行的,
p2一秒后调用p1这时p1才过了一秒,两秒后p1会返回状态。
p2返回p1的状态。
所以在3m后catch会得到失败的状态。
应用在实际中:
两个ajax,只有当两个都执行完后,才能返回状态,是p1的状态。
项目应用时当需要两个ajax都执行完才能做的操作时用这总方法。
它和链式ajax还是区别的。它是两个同时执行,全部成功返回状态。
then
它可以链式调用,
then(function(res){
return res.data
}).then(function(data){
console.log(data)
})
then会接受到上次then返回的值。
用then可以实现链式ajax调用
getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL);
}).then(function funcA(comments) {
console.log("Resolved: ", comments);
}, function funcB(err){
console.log("Rejected: ", err);
});
在then时返回一个promise
下个then会在promise返回状态后执行。
catch
用来指定发生错误时
Promise.all()
此方法用于将多个promise包装成一个新的promise对象,
var p=Promise.all([p1,p2,p3])
它会先把参数转换成promise对象
p的返回状态会在所有对象状态都返回时,由它们的返回值 组成一个数组,传递能then
当对象中一个返回rejected,p的状态也就是失败了。
Promise.resolve()
有时需要将现有对象转为Promise对象,Promise.resolve
方法就起到这个作用。
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
Promise.resolve('foo') // 等价于 new Promise(resolve => resolve('foo'))
Promise.reject()
Promise.reject(reason)
方法也会返回一个新的Promise实例,该实例的状态为rejected
。它的参数用法与Promise.resolve
方法完全一致。
done()
Promise对象的回调链,不管以then
方法或catch
方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个done
方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
promise可以和jenerator函数一起使用。
yield promise