学习目标:
了解promise的来源及语法,掌握promise及其函数的使用。
学习内容:
- promise是什么
- promise语法
- promise基础使用
学习产出:
1.promise是什么
概念:
Promise是es6里定义的一个对象,主要用来解决多个异步函数的同步调用问题。它通过状态来控制各个调用阶段的顺序,并通过回调将各个异步函数间的结果关联起来。异步的方法不会立即返回值,而是返回一个promise,以便在将来的某个时间点(依据promise状态判断什么时候)提供该值,由此可见一个 Promise 就是一个代理,代理异步函数执行的各个阶段,并可以设置在各个阶段处理的逻辑。
promise状态类型:
待定(pending):初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled):意味着操作成功,resolveFunc被调用时。
已拒绝(rejected):意味着操作失败,rejectFunc被调用时。
其中”已兑现“和”已拒绝“又称为“已敲定(settled)”。
一个promise对象的状态变更:
2. promise语法
了解一个对象通常需要了解它如何创建及里面的函数,因此语法从这两点入手:
创建对象:
创建对象(类似java中对象的创建),需要构造函数,使用new关键字调用构造函数后返回这个类的对象。
- Promise构造函数为:
Promise(executor)
- 因此语法为:
new Promise(executor)
- 这里的Promise是类,new Promise(()=>{})返回的 是Promise类的对象,即:
const isSuccess = true;
/* 构造函数入参(resolve, reject)=>{}是executor,在这里是匿名函数 */
const promiseObj = new Promise((resolve, reject) => {
if (isSuccess) {
resolve();
}
reject();
});
// promiseObj即是创建成功的Promise的对象。
说明:
- 构造函数入参executor是一个匿名函数,它在构造函数里会被执行。
- 这个executor函数又接收两个函数作为参数:resolve 和 reject,promise对象会有几种状态,resolve和reject的执行会改变Promise对象的状态。
注意:只有执行了resolve、reject其中之一时才会按顺序走到下面的then方法,且resolve/reject调用时传的参数值会透传给then方法(作为回调函数的入参),因此这两个函数传的参数值一般为当前异步函数的调用结果。
使用示例:
const myPromise = new Promise((resolve,reject)=>{
setTimeout(() => {
resolve("foo");
}, 300);
});
myPromise.then((value) => {
console.log(value); // 300ms执行完之后,才去调用的这里
});
console.log(promise1);
输出结果(注意顺序):
[object Promise]
"foo"
这两个函数(resolve、reject)的入参值可以是任何类型,不一定非是String类型。
对象上函数:
(1).then方法:
- 第一个参数是 Promise 兑现时(resolve())的回调函数,第二个参数是 Promise 拒绝时(reject())的回调函数。
- 每个 .then() 返回一个新生成的 Promise 对象,进而实现链式调用。
- 语法:
.then(handleFulfilledA, handleRejectedA)
- 返回值:会返回一个新的promise对象。
- 使用:
第一个参数是promise调用resolve后触发的回调函数,resolve传递的参数值会作为这个函数的入参。
第二个参数是promise调用reject后触发的回调函数,reject传递的参数值会作为这个函数的入参。
一般使用时then里面只会定义第一个参数,异常部分统一交给catch处理。
(2).catch方法:
- 接收一个Promise 对象被拒绝时异步执行的函数 作为参数。
- 语法:
catch(onRejected)
- 返回值:会返回一个新的promise对象。
- 触发场景:当前promise在then中抛出异常或者在构造函数中调用reject方法。
还有其他更多的情况,可以见链接:Promise.prototype.catch。
(3) .finally()方法:
- 接收一个不需要入参的函数onFinally作为参数,且返回值一般会被忽略。
- 语法:
finally(onFinally)
- 返回值:会返回一个新的promise对象。
- 触发场景:当前promise在 敲定(兑现或拒绝)时,即无论其结果如何时都会调用的函数,如果想在 promise 敲定时进行一些处理或者清理,可以放在这里。
还有其他更多的情况,可以见链接:Promise.prototype.finally。
(4) 类上函数,Promise 并发相关函数:
上三个【(1)、(2)、(3)】是对象上的方法,即通过new完的对象调用。下面这些方法是静态方法,即直接通过Promise类调用(这里只是简单列出,下篇进阶里讲代码)。
Promise.all()
在所有传入的 Promise 都被兑现时兑现;在任意一个 Promise 被拒绝时拒绝。
Promise.allSettled()
在所有的 Promise 都被敲定时兑现。
Promise.any()
在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。
Promise.race()
在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。
3.promise基础使用
异步查询后端api,并将结果处理后进行返回。
getResultDetailList = (params) => {
return defHttpSetpost({
url: Api.resultDetailUrl,
params,
});
};
// defHttpSetpost 方法 原项目代码简化后的一部分 没有验证 不一定可以运行 看逻辑即可
function defHttpSetpost(options){
this.axiosInstance = axios.create(options);
const transform = { options };
const transformRequestHook = transform || {}; // 需要对结果特殊处理的回调函数
return new Promise((resolve, reject) => {
this.axiosInstance
.request(conf) // 发起异步请求,request为axios自带异步请求后端函数
.then((res) => { // 获取结果
if (transformRequestHook && isFunction(transformRequestHook)) {
try {
const ret = transformRequestHook(res, opt);
resolve(ret); // 异步请求成功 对结果特殊处理后返回
}
catch (err) {
reject(err || new Error('request error!')); // 特殊处理结果报错返回
}
return;
}
resolve(res); // 异步请求成功 没有特殊结果处理时返回
})
.catch((e) => {
reject(e); // 异步请求出错 返回错误信息
});
});
}
调用时:
getResultDetailList(params).then((res)=>{console.log('=====调用结果为:',res)})
.catch((e)=>{ // 如果没有全局处理异常时 可以在这里抛出 有的话可以忽略
throw new Error('getResultDetailList接口请求异常:',e);
})
总结
上面主要列出语法和简单使用,中下篇再去讲述多个异步函数同步调用、并发调用的情况。