一、理解Promise
1.简介
new Promise(
/* 执行器 executor */
function (resovle, reject){
//执行耗时较长的异步操作
resolve(); //数据处理完成
reject(); //数据处理失败
}
).then(function A(){//成功下一步处理}, function B(){//失败处理});
Promise
是一个代理对象,他和原先要进行的操作并无关系。他通过引入一个回调,从而避免了更多的回调。Promise
的三个状态
pending表示 [待定] 初始状态、fulfilled表示 [实现] 操作状态、rejected表示 [被否决] 操作失败。
Promise 状态改变后就会调用 .then() 里面的响应函数继续后续步骤;
promise状态一旦变化,就不会在改变。
- then()函数
可以接受两个函数作为参数,分别表示fulfilled
和rejected
;
可以返回一个新的Promise
实例,所以可以链式调用;
当promise状态改变后,then会根据最终的状态来选择特定的响应函数来执行;
then()函数可以返回promise对象或其他值;
如果返回 promise 对象,name下一级的then()会在新的promise状态改变后执行;
如果返回的任意值,都会立即执行then()
// promise 实例
console.log(" 开始"); //首先输出
new Promise(resolve => {
setTimeout(() => {
resolve("执行Promise");
},2000);
}).then(value => {
//返回了promise实例,如果不返回promise,返回其他或者不返回,则当前的then会立即瞬间执行完毕
console.log(value); //紧接着输出
return new Promise(resolve => {
setTimeout(() => {
resolve(".then中返回的Promise实例");
},2000);
});
}).then(value => { //等到上面的 then 中操作执行完毕开始执行
console.log(value + "test"); //最后打印
});
- 错误处理
(1)reject(‘错误信息’).then(null,message => {});
(2)throw new Error(‘错误信息’).catch(message => {});
console.log(" 开始"); //首先输出
new Promise(resolve => {
setTimeout(() => {
throw new Error("发生了错误!");
},2000);
}).then(value => {
console.log(value);
}).catch(err => {
console.log("error = " + err.message);
});
console.log(" 开始"); //首先输出
new Promise(resolve => {
setTimeout(() => {
throw new Error("发生了错误!");
},2000);
}).then(value => {
console.log(value);
},err => {
console.log("error = " + err.message);
})
catch()方法会捕获在他上面出现的代码块的异常。
建议在每个队列上都加上 .catch() ,避免漏掉错误处理而造成的问题。
用途角度分析:
- 主要用于异步计算;
- 可以将异步操作对列化,按照期望的执行顺序,返回符合期望的结果;
- 可以在对象之间传递和操作Promise,帮助我们处理队列。
异步操作主要是以时间为主(如onload等);回调主要出现在Ajax、File API中。
二、案例整理
- 下面输出为:
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve();
console.log(2);
})
promise.then(() => {
console.log(3);
})
console.log(4);
// 1 2 4 3
promise 实例时,立刻执行,它的异步主要体现在了 .then() 、.catch() 中,
- promise状态变化
const promise = new Promise((resolve, reject) => {
resolve('success1');
reject('error');
resolve('success2');
});
promise.then((res) => {
console.log('then:', res);
}).catch((err) => {
console.log('catch:', err);
})
// then: success1
promise 状态一旦发生变化,就不会在改变,后面有多少resolve() / reject() 都不会再起作用。
- 参数问题
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
// 1
Promise.resolve(1)
.then((v) => {console.log(v);})
then() 方法接受一个函数作为参数,而如果传递的并非是一个函数,它实际上会将其解释为 then(null),这就会导致前一个 Promise 的结果会穿透下面。