JavaScript Promise 链式调用怎么写
你有没有遇到过这种情况:想同时处理好几件需要“排队做”的事,却被一堆嵌套代码绕得头晕眼花?比如先点外卖、等餐做好再取餐、取到餐再回家吃饭,要是用传统代码写,可能会把步骤一层套一层,像个“回调地狱”。今天要聊的JavaScript Promise链式调用,就是帮你把这些排队的事儿理得清清楚楚的好工具。
什么是Promise?先搞懂它的“身份”
Promise说白了就是一个“承诺”——你跟商家说“我下单了,你承诺10分钟内给我做好”,这个承诺就像一个容器,装着未来才会有的结果:要么成功(餐做好了),要么失败(商家说没食材了)。

举个生活化的例子:你让朋友帮忙取快递,朋友答应了,这就是一个Promise。如果快递取到了,就是“成功状态(resolve)”;如果快递丢了没取到,就是“失败状态(reject)”。
为什么要链式调用?告别“回调套娃”
假设你要做三件事:1. 查快递到哪了;2. 快递到了去取;3. 取完快递回家。用传统回调的写法,会是这样:
`javascript
// 假设有个查快递的函数
checkExpress((result) => {
// 查完再取快递,套一层
getParcel(result, (parcel) => {
// 取完再回家,又套一层
goHome(parcel, (home) => {
console.log("终于到家啦!");
});
});
});
`
你看,每多一件事就多一层嵌套,多到后面根本分不清哪层是哪层,这就是“回调地狱”。而Promise链式调用,就是把这些嵌套的“套娃”改成“排队走”:一件事做完,再做下一件,代码平平整整的。
链式调用怎么写?三步就学会
还是用刚才的快递例子,我们把三个函数改成返回Promise的版本,再用链式调用串起来:
**第一步:每个小任务返回Promise**
先把查快递、取快递、回家这三个操作,都改成“返回Promise”的函数——就像每个商家都能直接给你一个“承诺条”,而不是让你反复问。
`javascript
// 查快递,返回Promise
function checkExpress() {
return new Promise((resolve, reject) => {
// 模拟查快递的时间(比如2秒)
setTimeout(() => {
console.log("快递已到小区驿站");
resolve("驿站的快递柜"); // 把查的结果传给下一个任务
}, 2000);
});
}
// 取快递,返回Promise
function getParcel(location) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(在${location}取到了快递);
resolve("手里的快递");
}, 1500);
});
}
// 回家,返回Promise
function goHome(parcel) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(带着${parcel}回到家);
resolve("完成所有事");
}, 1000);
});
}
`
**第二步:用.then()把任务串起来**
Promise的.then()方法,就是“等这个承诺兑现后,再做下一件事”。链式调用就是把多个.then()连起来,像串珠子一样:
`javascript
checkExpress() // 第一个任务:查快递
.then(location => { // 查完的结果是location,传给下一个
return getParcel(location);
})
.then(parcel => { // 取完的结果是parcel,传给下一个
return goHome(parcel);
})
.then(finalResult => { // 最后得到最终结果
console.log("全部流程走完啦:" + finalResult);
});
`
**第三步:加个.catch()处理错误**
要是中间哪一步出问题了——比如查快递时发现快递丢了,链式调用不会崩溃,而是会直接跳到最近的.catch()处理错误,就像商家没食材时,你直接取消订单,不用硬等后面的步骤:
`javascript
checkExpress()
.then(location => getParcel(location))
.then(parcel => goHome(parcel))
.catch(error => {
console.log("出问题啦:" + error);
});
`
比如把查快递的函数里的resolve改成reject,就会触发.catch,直接输出“出问题啦:快递丢了”,后面的步骤都不会执行,代码干净又安全。
其实Promise链式调用的核心,就是把“嵌套的任务”改成“串行的任务”,就像你安排一天的行程:先吃早饭,再上班,再下班,不用把每个步骤都套在另一个里面。掌握这个写法,以后处理需要排队的异步任务,再也不会写得晕头转向了。