ES6 Promise
前言
由于js的异步执行特性,我们经常要使用到回调函数,然而当我们的回调函数还需要回调函数的时候,我们就逐渐步入了回调地狱的深渊。ES6(也叫ES2015)为了解决这个问题提出了Promse对象。
出现Promise的原因
当我们多个接口异步请求时,后一个请求依赖前一个请求的结果时,就会像面这样写。
$.ajax({
//...
})
.then(function (data) {
// 要在第一个请求成功后才可以执行下一步
$.ajax({
//...
})
.then(function (data) {
// ...
});
});缺点:
- 回调地狱,多个操作的时候就要无限嵌套回调函数了
- 如果前后请求没有依赖的时候,也要等待前一个接口完成才能发送请求了
什么是Promise?
一个Promise对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了Promise对象之后可以用一种链式调用的方式来组织代码,让代码更加直观。
resolve和reject
function helloWorld (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello World!");
} else {
reject("Good bye!");
}
});
}
helloWorld(true).then(function (message) {
alert(message);
}, function (error) {
alert(error);
});resolve 方法可以使Promise对象的状态改变为成功,同时传递一个参数用于后续成功后的操作,在这个例子当中就是 Hello World! 字符串。 reject 方法则是将Promise对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作。
promise三种状态
上面提到了 resolve 和 reject 可以改变Promise对象的状态,那么它究竟有哪些状态呢? Promise对象有三种对象 1 Fulfilled 可以理解为成功的状态 2 Rejected 可以理解为失败的状态 3 Pending 可以理解为Promise对象实例创建时候的初始状态
then和catch
helloWorld 的例子当中利用了 then(onFulfilld, onRejected) 方法来执行一个任务打印 "Hello World!",在多个任务的情况下then 方法同样可以用一个清晰的方式完成。
function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
}
function printWorld () {
alert("World");
}
function printExclamation () {
alert("!");
}
printHello(true)
.then(function(message){
alert(message);
})
.then(printWorld)
.then(printExclamation);catch 方法是 then(onFulfilled, onRejected) 方法当中 onRejected 函数的一个简单的写法,也就是说可以写成then(fn).catch(fn),相当于 then(fn).then(null, fn)。使用 catch 的写法比一般的写法更加清晰明确。
Promise.all 和 Promise.race
Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。
var p1 = new Promise(function (resolve) {
setTimeout(function () {
resolve("Hello");
}, 3000);
});
var p2 = new Promise(function (resolve) {
setTimeout(function () {
resolve("World");
}, 1000);
});
Promise.all([p1, p2]).then(function (result) {
console.log(result); // ["Hello", "World"]
});Promise.race 在promise数组中任何一个promise对象变成resolve或者reject,马上执行函数
// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
// 任何一个promise变为resolve或reject 的话程序就停止运行
Promise.race([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (value) {
console.log(value); // => 1
});特殊地方:
var promise = new Promise(function (resolve){
console.log("inner promise"); // 1
resolve(42);
});
promise.then(function(value){
console.log(value); // 3
});
console.log("outer promise"); // 2输出结果是:inner promise -> outer promise -> 42