异步JavaScript Promise代码停在‘order created’的问题排查与修复
回调地狱转Promise的问题分析与修复
原回调地狱代码
function createOrder() { setTimeout(function() { console.log("order created"); setTimeout(function() { console.log("order received"); setTimeout(function() { console.log("preparing food"); setTimeout(function() { console.log("order ready"); setTimeout(function() { console.log("order delivered"); }, 6000) }, 4000) }, 5000) }, 1000) }, 2000) } createOrder();
自行编写的Promise代码(仅输出第一个日志)
let p = new Promise(function (resolve, reject) { setTimeout(() => { console.log("order created"); }, 9000) }) p.then(function () { setTimeout(() => { console.log("order received"); }, 2000); }) .then(function () { setTimeout(() => { console.log("preparing food"); }, 3000); }) .then(function () { setTimeout(() => { console.log("order ready"); }, 4000); }) .then(function () { setTimeout(() => { console.log("order delivered"); }, 10000); })
问题原因
- Promise状态未触发变更:你创建的Promise内部,
setTimeout执行后仅打印了日志,却未调用resolve()方法。Promise会一直处于pending(等待)状态,后续的.then()回调只有在Promise状态变为fulfilled(成功)时才会执行,因此后面的所有回调都无法触发。 - 对比代码能执行的原因:对比代码的
createOrder()函数返回的Promise内部,打印日志后调用了resolve(),将Promise状态改为fulfilled,第一个.then()因此得以执行。但需注意,对比代码的.then()未返回新的Promise,所有.then()会在第一个Promise完成后几乎同时触发,日志输出顺序仅由setTimeout的延迟时间决定,并非严格复刻原回调地狱的顺序执行逻辑。
修复方法
要实现与原回调地狱一致的顺序执行效果,需在每个.then()中返回新的Promise,并在setTimeout内部调用resolve(),让后续.then()等待当前异步操作完成后再执行:
let p = new Promise(function (resolve, reject) { setTimeout(() => { console.log("订单已创建"); resolve(); // 触发Promise状态变更 }, 2000) }) p.then(function () { return new Promise(resolve => { setTimeout(() => { console.log("订单已接收"); resolve(); }, 1000); }) }) .then(function () { return new Promise(resolve => { setTimeout(() => { console.log("正在准备食物"); resolve(); }, 5000); }) }) .then(function () { return new Promise(resolve => { setTimeout(() => { console.log("订单已准备好"); resolve(); }, 4000); }) }) .then(function () { return new Promise(resolve => { setTimeout(() => { console.log("订单已配送"); resolve(); }, 6000); }) })
关键要点
- Promise必须通过
resolve()或reject()变更状态,否则后续的.then()/.catch()不会执行。 - 要实现异步操作的顺序执行,每个
.then()必须返回新的Promise,确保下一个.then()等待当前异步任务完成。
内容的提问来源于stack exchange,提问作者kdqdmmg0
相关产品推荐
相关产品推荐

