提示:
参考来自:Promise和Async/Await用法整理
一、Promise是什么?
从语法上来说Promise是一个对象,从它可以获取异步操作的信息。
二、如何使用Promise
1.Promise对象的基本语法
基本语法如下:
let p = new Promise((resolve,reject) => {
resolve('success')
});
p.then(result => {
console.log(result);//success
});
Promise对象的三个特点和状态
2.Promise状态
示例如下:
let p = new Promise((resolve,reject) => {
//...
resolve('success');
console.log('after resolve');
reject('error');
});
p.then(result => {
console.log(result);
});
p.catch(result => {
console.log(result);
})
输出:after resolve
success
resolve下面的语句其实是可以执行的,那么为什么reject的状态信息在下面没有接受到呢?这就是因为Promise对象的特点:状态的凝固。new出一个Promise对象时,这个对象的起始状 态就是Pending状态,在根据resolve或reject返回Fulfilled状态/Rejected状态。
3.链式调用
let p = new Promise((resolve,reject) => {
reject('reject');
});
let resultP = p.then(null,result => {
console.log(result);
});
console.log(resultP);
结果:
Promise { <pending> }
reject
js的执行顺序就是这样,同步->异步->回调,在同步执行的时候,Promise对象还处于pending的状态,也说明了这个then返回的是一个Promise对象。
而且必须在then里面给一个返回值,才能继续调用,否则undefined。
4.Promise.prototype.then
then()方法返回的是一个promise对象。它最多需要有两个参数:Promise的成功和失败情况的回调函数。
const promise1 = new Promise((resolve, reject) => {
resolve('Success!');
});
promise1.then((value) => {
console.log(value);
// expected output: "Success!"
});
注意:如果忽略针对某个状态的回调函数参数,或者提供非函数参数,那么then方法将会丢失关于该状态的回调函数信息,但是并不会产生错误。如果调用then的Promise的状态(fulfillment或rejection)发生改变,但是then中并没有关于这种状态的回调函数,那么then将创建一个没有经过回调函数处理的新Promise对象,这个新Promise只是简单地接受调用这个then的原Promise的终态作为它的终态。
p.then(onFulfilled[, onRejected]);
p.then(value => {
//fulfillment
},reason => {
//rejection
});
then 方法的异步性的例子
const promise5 = Promise.resolve('the best one');
let thenProm = promise5.then(value => {
console.log("then 示例,value的值:"+value);
return value;
});
console.log(thenProm);
setTimeout(() => {
console.log(thenProm)
})
结果如图:
(1)then多次调用形成调用链,每个then返回的都必须是一个promise。如果then方法里面的onFulfilled函数返回的不是promise,比如是Number或String,那么架构会用Promise.resolve(return的返回值)包装成一个resolved状态的promise返回。传入下一个then不是promise,而是resolve方法的参数。
(2)then的调用链可以有多个then,但最后一般需要有个catch来捕捉前面某个then的promise通过reject(error),then的调用链中只要有一个then边长rejected状态,那么后面的then都不会执行,直接跳到catch。catch也可以捕捉promise和then里面的error,类似加上了try catch的效果,但是如果function里面如果有异步代码,是没有办法catch到的。
(3)then里面的function onFulfilled必须return之后下一个then才会执行,而且会把返回值传递给下个then的onFullflled函数,所以then的调用链可以构成一个顺序执行的方法链,每个方法都依赖于前一个执行之后的返回值(如果没有return,会传递undefined给下一个方法),尽量不要再then中使用异步函数(像是setTimeout())