Promise函数详解
Javascript执行环境是单线程的,也就是说JS环境中负责解释和执行的线程只有一个,一次只能完成一项任务,这个任务执行完后才能执行下一个,因此Javascript中存在大量的异步操作和回调函数。
Promise 是异步编程的一种解决方案,是为了解决地域回调问题,比传统的解决方案——回调函数和事件——更合理和更强大。
promise是一个构造函数,new 出来的 Promise 实例对象,代表一个异步操作,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
Promise的状态
Promise对象的状态有3个,分别是pending(进行中)、fulfilled(已完成)、rejected(已失败)。Promise对象一旦进入了某一个状态,就不会再转成其他状态了(主要是后面两种状态,fulfilled和rejected)。如一旦调用了resolve函数,就是fulfilled的状态,就不会再调用reject函数了。
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfilled:已成功,当我们回调了resolve函数时,就处于该状态。
rejected:以失败,当我们回调了reject函数时,就处于该状态。
.then和.catch函数注意点:
.then()函数和.catch()都需要Promise对象才能调用,再使用这两个函数的时候,需要注意的地方如下:
1、调用 .then() 方法时,成功的回调函数是必选的,失败的回调函数是可选的。即参数可以为.then(resolve=>{},reject=>{})或.then(resolve=>{}) 这两种。
2、resolve函数返回的是Promise对象,哪怕使用 return ‘bbb’;这样的显式返回,最后也会转成Promise对象返回出去。也可以人工显式指定返回,如以下所示。新返回的Promise对象可以再跟then函数,一直跟下去。如果没有return这条语句,则默认返回对象的参数是undefinded,即res为undefined。
p.then(res => {
console.log('11-' + res);
return 'AAA'; // 相当于Promise.resolve("AAA")
}).then(res => {
console.log('22-' + res);
return new Promise((resolve, reject) => {
resolve(res); // 此处还可以调用reject
})
}).then(res => {
return Promise.resolve(res);
})
3、reject返回的是空,或者说无返回。因为无返回,故后面跟then或catch函数无意义,也不会执行。
let newPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('BBB');
}, 1000);
});
newPromise.then(null, error => {
console.log("then:" + error);
}).catch(error => {
// 这里的代码无意义,没有被执行
console.log("catch:" + error);
})
4、多次调用Promise.then()函数,原理一致。传入的数据永远是调用对象的数据。
let newPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('BBB');
}, 1000);
});
newPromise.then(res => {
console.log("1:", res); // 输出 1:BBB
return "ccc"
});
newPromise.then(res => {
console.log("2:", res); // 输出 2: BBB,而不是 2: ccc
});
newPromise.then(null, error => {
console.log("3:", error); // 不会执行,因为是已完成状态
});
let newPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('BBB');
}, 1000);
});
newPromise.then(null, error => {
console.log("4:", error); // 4: BBB
});
newPromise.catch(error => {
console.log("5:", error); // 5:BBB
})
5、catch函数。该函数有两个作用,一个是等同于then(null,reject=>{});一个是捕获resolve中的异常。如果不希望前面的错误导致后续的 .then 无法正常执行,则可以将 .catch 的调用提前。
let newPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('BBB');
}, 1000);
});
newPromise.then(res => {
console.log("6:", res);
throw new Error('newError') // 6: BBB
}).catch(error => {
console.log("7:", error); // 7: Error: newError,捕获resolve中的异常
});
Promise.all():等待机制
Promise.all()
方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后并且执行结果都是成功的时候才会执行下一步的 .then 操作(等待机制)
Promise.all([
new Promise((resolve, reject) => {
console.log("准备付钱");
setTimeout(() => {
console.log("支付成功");
resolve("Pay Success")
}, 2000);
}),
new Promise((resolve, reject) => {
console.log("商家发货");
setTimeout(() => {
console.log("收到货物");
resolve("Send Success")
}, 1000);
})
]).then(result => {
console.log("交易完成");
console.log(result);
})
Promise.race():赛跑机制
Promise.race()
方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即执行下一步的 .then 操作(赛跑机制)。
Promise.race([
new Promise((resolve, reject) => {
console.log("准备付钱");
setTimeout(() => {
console.log("支付成功");
resolve("Pay Success")
}, 1000);
}),
new Promise((resolve, reject) => {
console.log("商家发货");
setTimeout(() => {
console.log("收到货物失败");
reject("Send Failure");
}, 2000);
})
]).then(res => {
console.log("success":res);
}).catch(error => {
console.log("error":error);
})