ref
setTimeout(handler, ?timeout, ...arguments)
setInterval(handler, ?timeout, ...arguments)
Promise
intro
Promise
是JS异步编程的一种解决方案。
Promise
对象可以表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。
-
三种状态
对象状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:pending
: 悬而未决的,待定的。初始状态。fulfilled
: 操作成功。rejected
: 被拒绝的,即操作失败。
-
状态改变
只有异步操作的结果,可以决定当前是哪种状态,其他任何操作都无法改变这个状态(状态无法再次更改)。这也是Promise
(承诺)的类名的由来,表示其他手段无法改变。
两种变化:pending
->fulfilled
pending
->rejected
Promise
与事件Event
的区别是:事件Event
如果被错过,再去监听,是得不到结果的。 -
好处
使得 嵌套的异步操作更容易书写,从回调函数的“横向发展”改为“向下发展”(链式调用
)。
即 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。 -
缺点
Promise
无法取消,一旦创建就会立即执行,无法中途执行。- 如果不设置对应的回调函数处理错误,在
Promise
内部抛出的错误,不会反映到外部。 - 当处于
pending
状态时,无法得知当前的进展(刚刚开始还是将要完成)。
API
-
构造方法
new Promise(function executor(resolve, reject) {...})
如果一切正常,调用resolve
,对应fulfilled
状态。
否则调用reject
。 -
原型方法(可链式操作)
p.then(?onfulfilled, ?onrejected)
可以指定操作成功或操作失败时执行的回调。
p.catch(?onrejected)
指定操作失败时执行的回调。
p.finally(?onfinally)
最后一定会执行的回调
p.then(onfulfilled, onrejected)
相当于:
p.then(onfulfilled).catch(onrejected)
- 静态方法
Promise.all(iterable)
返回一个新的promise
,该对象只有在iterable
中所有的promise
对象都操作成功的时候才会触发成功。即&&
关系。
Promise.race(itarable)
当iterable
中的任意一个子promise
出现结果(成功,失败)后,这个结果作为新返回的promise
的参数。
Promise.resolve(value)
返回一个状态由给定value决定的Promise对象
Promise.reject(reason)
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
demo
Promise
对象的原型方法then(), catch()
等会返回promise
对象,所以可链式调用。
上一个执行方法传出的返回值会作为下一个执行方法的传入参数。
var p = new Promise(function(resolve, reject) {
resolve(1);
}).then(function(value) {
console.log(value); // 1
return value * 2;
}).then(function(value) {
console.log(value); // 2
// 不返回值
}).then(function(value) {
console.log(value); // undefined
}).catch(function(v) {
console.log(v);
});
大多数浏览器不能终止的promise
链中的rejection
,推荐最后加上:
.catch(error => console.log(error.message));
Promise AJAX
function ajax(URL) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open("GET", URL, true);
req.onload = function() {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function() {
reject(new Error(req.statusText));
};
req.send();
});
}
var URL = "...";
ajax(URL).then(function onFulfilled(value) {
console.log("成功:", value);
}).catch(function onRejected(error) {
console.log("失败", error);
});
onreject()
方法的参数通常是Error
类型。
而then()
方法的参数可以是常见类型,也可以是另一个Promise
实例。