javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS resolve和reject执行顺序

一篇文章让你搞懂JS中new Promise的resolve和reject执行顺序

作者:正义的大古

在JavaScript中new Promise是用来创建一个Promise对象的构造函数,它接受一个执行器函数作为参数,这篇文章主要介绍了JS中new Promise的resolve和reject执行顺序的相关资料,需要的朋友可以参考下

一、在Promise里,如果resolve和reject同时存在,且没有条件约束(同步调用),或者有条件约束(异步/条件判断),它们的执行顺序是怎样的?

1.resolve和reject同级,且没有条件约束(同步调用)

示例代码:

new Promise((resolve, reject) => {
    resolve("成功"); // (A)
    reject("失败");  // (B)
}).then(
    (res) => console.log("then:", res),
    (err) => console.log("catch:", err)
);

执行顺序:

  1. resolve("成功") (A) 先执行,Promise 状态变为 fulfilled

  2. reject("失败") (B) 也会执行,但由于 Promise 状态已经变成 fulfilled,它会被 忽略

  3. 最终进入 .then() 的成功回调,输出 "then: 成功"

结论:

✅ resolve 先执行,reject 被忽略(因为 Promise 状态一旦改变就不能再变)。

2.resolve和reject有条件约束(异步/条件判断)

(1) 异步任务(如setTimeout)决定执行顺序

示例代码:

new Promise((resolve, reject) => {
    setTimeout(() => resolve("成功"), 1000); // (A) 1秒后执行
    setTimeout(() => reject("失败"), 500);  // (B) 0.5秒后执行
}).then(
    (res) => console.log("then:", res),
    (err) => console.log("catch:", err)
);

执行顺序:

  1. reject("失败") (B) 先执行(500ms < 1000ms),Promise 状态变为 rejected

  2. resolve("成功") (A) 1秒后执行,但 Promise 已经是 rejected,所以它被 忽略

  3. 最终进入 .then() 的失败回调,输出 "catch: 失败"

结论:

✅ 先执行的(reject)生效,后执行的(resolve)被忽略

(2) 条件判断(如if-else)决定执行顺序

示例代码:

let condition = true;

new Promise((resolve, reject) => {
    if (condition) {
        resolve("成功"); // (A) 执行
    } else {
        reject("失败");  // (B) 不执行
    }
}).then(
    (res) => console.log("then:", res),
    (err) => console.log("catch:", err)
);

执行顺序:

  1. condition 为 true,所以 resolve("成功") (A) 执行,Promise 状态变为 fulfilled

  2. reject("失败") (B) 不会执行。

  3. 最终进入 .then() 的成功回调,输出 "then: 成功"

结论:

✅ 条件决定哪个先执行,另一个不会执行

总结

情况执行顺序结果
resolve 和 reject 同步调用(无约束)resolve 先执行,reject 被忽略走 then 成功回调
resolve 和 reject 异步调用(如 setTimeout)先调用的生效,后调用的被忽略取决于谁先执行
resolve 和 reject 有条件约束(如 if-else)满足条件的执行,另一个不执行由条件决定

核心规则

  1. Promise 的状态一旦改变(fulfilled/rejected),就不能再变

  2. 同步代码中,resolve 和 reject 谁在前谁生效

  3. 异步代码中,取决于哪个回调先执行

  4. 条件约束下,满足条件的执行,另一个不执行

二、在Promise链式调用(.then())的情况下,后续是否还会执行resolve或reject取决于前一个Promise的状态以及.then()回调的返回值。

1..then()的基本行为

.then() 会返回一个新的 Promise,它的状态由它的回调函数决定:

示例 1:.then()返回普通值

new Promise((resolve) => resolve("A"))
  .then((res) => {
    console.log(res); // "A"
    return "B"; // ✅ 相当于 resolve("B")
  })
  .then((res) => {
    console.log(res); // "B"
  });

执行流程:

  1. 第一个 Promise resolve("A")

  2. 第一个 .then() 接收 "A",并返回 "B"(相当于 resolve("B"))。

  3. 第二个 .then() 接收 "B"

示例 2:.then()抛出错误

new Promise((resolve) => resolve("A"))
  .then((res) => {
    console.log(res); // "A"
    throw new Error("Oops!"); // ❌ 相当于 reject(Error("Oops!"))
  })
  .then(
    (res) => console.log("成功", res), // 不会执行
    (err) => console.log("失败", err)  // 捕获错误:"失败 Error: Oops!"
  );

执行流程:

  1. 第一个 Promise resolve("A")

  2. 第一个 .then() 抛出错误,导致新的 Promise reject

  3. 第二个 .then() 的失败回调捕获错误。

2. 后续是否还能执行resolve或reject?

情况 1:.then()返回新的Promise

如果 .then() 返回一个新的 Promise,那么它的 resolve/reject 会影响后续的链式调用。

示例:

new Promise((resolve) => resolve("A"))
  .then((res) => {
    console.log(res); // "A"
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve("B"), 1000); // 1秒后 resolve("B")
    });
  })
  .then((res) => {
    console.log(res); // "B"(1秒后打印)
  });

执行流程:

  1. 第一个 Promise resolve("A")

  2. 第一个 .then() 返回一个新的 Promise,1秒后 resolve("B")

  3. 第二个 .then() 等待这个 Promise 完成,最终接收 "B"

情况 2:.then()内部再次调用resolve/reject

如果 .then() 内部手动创建 Promise 并调用 resolve/reject,会影响后续流程。

示例:

new Promise((resolve) => resolve("A"))
  .then((res) => {
    console.log(res); // "A"
    return new Promise((resolve, reject) => {
      resolve("B"); // ✅ 手动 resolve
      reject("Error"); // ❌ 会被忽略(Promise 状态已改变)
    });
  })
  .then(
    (res) => console.log("成功", res), // "成功 B"
    (err) => console.log("失败", err)
  );

执行流程:

  1. 第一个 Promise resolve("A")

  2. 第一个 .then() 返回一个新的 Promise,并立即 resolve("B")reject("Error") 被忽略。

  3. 第二个 .then() 接收 "B"

3. 关键结论

  1. .then() 会返回一个新的 Promise,它的状态由回调决定:

    • 如果回调返回普通值 → 新 Promise resolve 该值。

    • 如果回调抛出错误 → 新 Promise reject 该错误。

    • 如果回调返回 Promise → 新 Promise 跟随它的状态。

  2. 后续的 resolve/reject 由 .then() 的回调决定,而不是最初的那个 Promise

  3. Promise 状态一旦改变就不能再变,所以如果 resolve 和 reject 同时出现,先执行的生效,后执行的被忽略。

4.总结

情况是否还能执行 resolve/reject?说明
.then() 返回普通值✅ 相当于 resolve(返回值)后续 .then() 会接收该值
.then() 抛出错误✅ 相当于 reject(错误)后续 .catch() 会捕获
.then() 返回 Promise✅ 跟随该 Promise 的 resolve/reject后续 .then() 或 .catch() 取决于它
Promise 已经 resolve/reject❌ 无法再改变状态后续调用 resolve/reject 无效

核心规则:

  1. Promise 链式调用的每一步都是一个新的 Promise

  2. 后续的 resolve/reject 由 .then() 或 .catch() 的回调决定

  3. 一旦 Promise 状态改变,就不能再变,所以 resolve 和 reject 不会冲突。

三、即使Promise被reject,仍然可以继续调用.then()或.catch(),但执行逻辑有所不同。关键在于Promise的链式调用如何处理rejected状态。

1.reject后如何继续调用?

(1) 使用.catch()捕获错误

.catch() 专门用于处理 rejected 状态的 Promise,类似于 try/catch
示例:

new Promise((resolve, reject) => {
    reject("失败"); // ❌ Promise 被 reject
})
.then((res) => {
    console.log("成功:", res); // 不会执行
})
.catch((err) => {
    console.log("捕获错误:", err); // 输出:"捕获错误: 失败"
    return "错误已处理"; // ✅ 返回一个新值,相当于 resolve("错误已处理")
})
.then((res) => {
    console.log("后续处理:", res); // 输出:"后续处理: 错误已处理"
});

执行流程:

  1. Promise 被 reject("失败")

  2. 第一个 .then() 被跳过(因为 Promise 是 rejected 状态)。

  3. .catch() 捕获错误,并返回一个新值(相当于 resolve("错误已处理"))。

  4. 后续的 .then() 接收到 "错误已处理"

(2) 使用.then()的第二个参数(错误回调)

.then() 可以接受两个参数:

new Promise((resolve, reject) => {
    reject("失败"); // ❌ Promise 被 reject
})
.then(
    (res) => console.log("成功:", res), // 不会执行
    (err) => {
        console.log("失败回调:", err); // 输出:"失败回调: 失败"
        return "从错误中恢复"; // ✅ 返回一个新值,相当于 resolve("从错误中恢复")
    }
)
.then((res) => {
    console.log("后续处理:", res); // 输出:"后续处理: 从错误中恢复"
});

执行流程:

  1. Promise 被 reject("失败")

  2. .then() 的第二个参数(错误回调)被执行,并返回 "从错误中恢复"。

  3. 后续的 .then() 接收到 "从错误中恢复"。

2. 关键区别:.catch()vs.then()的第二个参数

方式特点适用场景
.catch()专用于错误处理,代码更清晰链式调用中统一处理错误
.then() 的第二个参数直接绑定到当前 .then()需要针对特定步骤处理错误

推荐使用 .catch(),因为它更符合链式调用的习惯,且能捕获前面所有 .then() 中的错误。

3. 如果既不.catch()也不传错误回调?

如果 reject 后没有错误处理,控制台会报 Uncaught (in promise) 警告,但后续 .then() 仍会执行(只是接收不到 reject 的值)。

示例:

new Promise((resolve, reject) => {
    reject("失败"); // ❌ 未捕获的错误
})
.then((res) => {
    console.log("成功:", res); // 不会执行
})
.then((res) => {
    console.log("仍然执行,但 res=", res); // 输出:"仍然执行,但 res= undefined"
});

执行结果:

  1. 控制台警告:Uncaught (in promise) 失败

  2. 最后一个 .then() 仍然执行,但 res 是 undefined(因为没有前一步的返回值)。

4. 总结

问题答案
reject 后还能继续调用 .then() 吗?✅ 可以,但需要通过 .catch() 或 .then() 的第二个参数处理错误。
reject 后不处理会怎样?❌ 控制台报 Uncaught (in promise) 警告,但后续 .then() 仍会执行(res=undefined)。
如何优雅地处理 reject?使用 .catch() 或 .then() 的第二个参数,并返回新值以继续链式调用。

最终建议:

在链式调用中,始终用 .catch() 处理错误,避免未捕获的 Promise 错误!

到此这篇关于JS中new Promise的resolve和reject执行顺序的文章就介绍到这了,更多相关JS resolve和reject执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文