本文深入解析ES6中Promise的核心机制,涵盖pending、resolved和rejected三种状态及其不可逆特性。详细讲解实例方法then、catch、finally及对象方法Promise.all与Promise.race的用法,结合代码示例说明如何处理异步回调地狱,并对比async/await在ES8中的演进,帮助开发者掌握现代前端异步编程的最佳实践。
一、Promise的概念定义
Promise是ES6中处理异步编程的核心方案(后续ES8的async/await基于此),语法上表现为一个对象或构造函数,用于封装异步操作并获取其成功或失败结果。
二、Promise的应用场景
主要应用于ajax和axios请求。因网络延迟导致返回值时间不确定,而后续代码依赖前次请求结果,故需通过Promise等待结果返回后再执行后续逻辑。
三、Promise的优势
1. 消除多层异步调用嵌套(即回调地狱) 2. 提供简洁API,简化异步操作控制(解决js执行机制导致的异步问题) 这两点在ES6专栏文章中有详细介绍,此处略过。
四、Promise的三种状态
Promise对象具备以下三种状态:
1. pending:等待中或进行中,表示尚未获得结果。
2. resolved (Fulfilled):已完成,表示已获得预期结果,可继续执行后续操作。
3. rejected:表示获得结果但非预期,因此拒绝执行。
这三种状态不受外界影响,且只能从pending单向转变为resolved或rejected,该过程不可逆。
五、Promise的具体用法
1. Promise的实例方法
① then():用于获取异步任务的成功结果。
② catch():用于捕获并获取异常信息。
③ finally():无论成功与否均会执行(注:此非正式标准)。
注意:then方法可接受两个函数,第一个为状态成功时的回调,第二个为状态失败时的回调(通常省略第二个,改用catch捕获失败异常)。
2. Promise的对象方法(p1, p2, p3为Promise实例对象)
① Promise.all():并发处理多个异步任务,需所有任务均完成才能获取结果。
Promise.all( [p1,p2,p3] ) .then ( (result) => {consoleog (result)
})② Promise.race():并发处理多个异步任务,只要有一个任务完成即可获取结果。
Promise.race ( [p1,p2,p3] ).then ( (result)=>{
console. log (result)
})六、Promise的运行特点
1. 在Promise构造函数中,第一个参数为执行函数。
2. 该执行函数用于处理Promise状态变化,其第一个参数表示成功(resolve),第二个参数表示失败(reject),两者均为函数,作用分别是将状态修改为resolved(成功)和rejected(失败)。
<script>
function fn(flag) {
//构造函数
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise状态为成功!')
};
if (flag === false) {
reject('promise状态失败!')
};
})
}
console.log(fn(true));
</script>控制台运行示例:

3. Promise对象的then方法可接收构造函数中处理的状态变化,并分别执行。then方法包含两个函数参数,第一个接收resolved(成功)的执行,第二个接收reject(失败)的执行。
<script>
function fn(flag) {
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise状态为成功!')
};
if (flag === false) {
reject('promise状态失败!')
};
}).then(function(res) {
console.log(res);
},
function(err) {
console.log(err);
})
}
fn(true)
fn(false)
</script>控制台运行示例:

4. Promise状态只能从“未完成”转变为“完成”或“失败”,且状态一旦改变不可逆转。
Promise的异步结果仅在完成状态时返回,开发中根据结果选择状态,再根据状态决定是否执行then()。
实例化的Promise内部会立即执行,而then方法中的异步回调函数会在脚本中所有同步任务完成后才执行,因此Promise的异步回调结果最后输出。示例代码如下:
var promise = new Promise(function(resolve, reject) {
console.log('Promise instance');
resolve();
});
promise.then(function() {
console.log('resolved result');
});
for(var i=0;i<100;i++) {
console.log(i);
/*
Promise instance
1
2
3
...
99
100
resolved result
*/5. Promise.then()方法详解
① then()函数返回的实际也是一个Promise对象(无论函数内部返回何种类型数据,函数都会加工并返回一个Promise对象)。
<script>
function fn(flag) {
return new Promise(function(resolve, reject) {
if (flag === true) {
resolve('promise状态为成功!')
};
if (flag === false) {
reject('promise状态失败!')
};
})
}
console.log(fn(true).then());
</script>控制台运行示例:

② 当then()函数内部返回普通值(非Promise类型属性)时,该普通值会直接传递给下一个then,通过then参数中函数的参数接收该值。
此时then()函数返回的Promise对象状态为成功(resolved),其返回值为对象的成功值。例如return 123,返回的Promise对象值为123;若无返回值,则为undefined。
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
})
});
let result = p.then(value => {
return 123;
}, reason => {
console.log(reason)
})
console.log(result);
result.then(function(res) {
console.log(res);
})
</script>控制台运行示例:

③ 当then()函数内部返回的是Promise类型的对象时,then()函数返回的Promise对象的状态值即为该Promise对象的状态值,成功值亦如此,返回的该Promise对象会调用下一个then方法。
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
})
});
let result = p.then(value => {
return new Promise((resolve, reject) => {
resolve('ok')
})
}, reason => {
console.log(reason)
})
console.log(result);
result.then(function(res) {
console.log(res);
})
</script>控制台运行示例:

④ 当then()函数内部抛出异常时,则then()函数的返回值状态也为rejected。
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
})
});
let result = p.then(value => {
throw 123
}, reason => {
console.log(reason)
})
console.log(result);
</script>控制台运行示例:

6. Promise.catch()方法详解
① catch()函数仅包含一个回调函数,意味着如果Promise对象状态为失败,就会调用catch()方法并执行回调。
//catch()函数只有一个回调函数,意味着如果Promise对象状态为失败就会调用catch()方法并且调用回调函数
<script>
const p = new Promise((resolve, reject) => {
setTimeout(()=>{
reject('出错啦')
},1000)
})
p.catch(reason => {
console.log(reason)
})
</script>控制台运行示例:

七、总结
1. Promise本质上是一个对象或构造函数。
2. Promise(ES6)的出现旨在解决异步编程和回调地狱等问题;async和await(ES8)的出现则是基于Promise的解决异步编程的终极方案(旨在简化代码等)。
3. 在前端开发中,ajax和axios均涉及异步编程,且axios基于Promise,因此必须掌握Promise以及async和await与Promise搭配的使用。
到此这篇关于ES6中Promise详解及用法的文章就介绍到这了,更多相关ES6 Promise用法内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!