Promise基础(消化错误和抛出错误)

本文详细解析了JavaScript中Promise对象的工作原理,包括then、catch、finally等方法的使用方式及内部实现机制,帮助读者深入理解异步编程。
部署运行你感兴趣的模型镜像

then

then 函数的会接收两个回调函数,一个是 onFulfilled 函数,一个是 onRejected 函数

如果这两个回调函数没有写返回值,默认会 return undefined;

进入下一个函数的 onFulfilled 函数中

const p = new Promise((resolve, reject) => {
  resolve(22);
});
p.then(
  (success1) => {
    console.log("success1", success1); // "success2" 22
    // 没写 return 默认返回 return undefined
  },
  (err1) => {
    console.log("err1", err1);
  }
).then(
  (success2) => {
    console.log("success2", success2); // "success2" undefined
  },
  (err2) => {
    console.log("err2", err2);
  }
);

在这两个回调中 return xxx ,相当于调用 return new Promise((resolve) => resolve(xxx));

const p = new Promise((resolve, reject) => {
  resolve(22);
});
p.then(
  (success1) => {
    return new Promise((resolve, reject) => resolve("success"));
    // 等价于
    return "success";
  },
  (err1) => {
    console.log("err1", err1);
  }
).then(
  (success2) => {
    console.log("success2", success2); // "success2" "success"
  },
  (err2) => {
    console.log("err2", err2);
  }
);

onFulfilled 函数和 onRejected 函数中默认返回的都是成功,如果需要返回失败需要显示调用 reject 或者用 throw 抛出错误可以

const p = new Promise((resolve, reject) => {
  resolve(22);
});
p.then(
  (success1) => {
    return new Promise((resolve, reject) => reject("error"));
    // 等价于
    // throw "error";
  },
  (err1) => {
    console.log("err1", err1);
  }
).then(
  (success2) => {
    console.log("success2", success2);
  },
  (err2) => {
    console.log("err2", err2); // "err2" error
  }
);

总结:在 then 回调中 return xxx 会被自动包装成 return new Promise((resolve) => resolve(xxx));

catch

catch 是用来处理 rejected 状态,是 then 函数的一种特例,相当于 then(null, (err) => {});

catch 为什么能捕获前面的错误?

onRejected 函数中,如果没有显示抛出错误,默认会 return undefined; 进入一下个 onFulfilled 函数

finally

finally 不管当前 promise 是什么状态都会执行,也是 then 函数的一种特例,相当于 `then(result => result, err => new Promsie((_, reject) => reject(err)));

Promise.resolve

Promise.resolvePromisefulfilled 状态时的简写,相当于 new Promise(resolve => resolve(xxx))

onFulfilled 函数接收参数

  • 当参数是普通参数时,会直接传递给后面 then 函数
    new Promise((resolve) => resolve({ name: "uccs" })).then((data) => {
      console.log(data);
    });
    
  • 当参数是 Promise 对象时,后面的 then 会根据传递的 Promise 对象的状态变化执行哪一个回调
    const p = new Promise((resolve, reject) => {
      setTimeout(resolve, 1000, "我执行了");
    });
    new Promise((resolve) => resolve(p)).then((data) => {
      console.log(data);
    });
    
  • 具有 then 方法的对象
    • 用这种这种方式,如果需要改变 Promise 状态是,不能使用 return 形式,这个 then 方法也是有两个回调函数的:onFulfilledonRejected
    const thenable = {
      then(resolve, reject) {
        console.log("thenable");
      },
    };
    new Promise((resolve) => resolve(thenable)).then((data) => {
      console.log(data);
    });
    

Promise.reject

Promise.rejectPromiserejected 状态是的简写,相当于 new Promise((_, reject) => reject(xxx))

onRejected 函数不管接收什么参数,都会原封不动的向后传递,作为后续方法的参数

您可能感兴趣的与本文相关的镜像

HunyuanVideo-Foley

HunyuanVideo-Foley

语音合成

HunyuanVideo-Foley是由腾讯混元2025年8月28日宣布开源端到端视频音效生成模型,用户只需输入视频和文字,就能为视频匹配电影级音效

<think> 我们正在讨论JavaScriptPromise如何抛出错误。根据引用[2]引用[3],Promise抛出错误主要有两种方式: 1.Promise的执行器(executor)中使用reject函数。 2.then链中使用throw语句抛出错误,该错误会被后面的catch捕获。 另外,引用[3]还说明了使用async/await时,可以通过Promisereject抛出错误,然后在await表达式中使用catch捕获。 因此,我们可以总结如下: </think> 在 JavaScript 中使用 Promise 抛出错误主要有以下几种方法,这些方法都基于 Promise错误处理机制: ### 1. 使用 `reject()` 方法(推荐) 在 Promise 构造函数中使用 `reject()` 函数抛出错误: ```javascript function fetchData(url) { return new Promise((resolve, reject) => { if (!url) { reject(new Error('URL is required')); // 抛出错误 } // 正常逻辑 resolve('Data loaded'); }); } // 使用示例 fetchData() .then(data => console.log(data)) .catch(error => console.error(error.message)); // 捕获错误:URL is required ``` ### 2. 在 `then()` 链中使用 `throw` 在 Promise 链的 `then()` 处理函数中抛出错误: ```javascript validateInput(input) .then(data => { if (!data.isValid) { throw new Error('Invalid input'); // 抛出错误 } return processData(data); }) .catch(error => console.error(error)); // 捕获错误 ``` ### 3. `async/await` 中使用 `throw` 在 `async` 函数中结合 `throw` `try/catch`: ```javascript async function getUser(id) { if (!id) throw new Error('ID is required'); // 直接抛出错误 try { const response = await fetch(`/api/users/${id}`); if (!response.ok) throw new Error('API request failed'); // 条件错误 return response.json(); } catch (error) { console.error('Request failed:', error.message); } } // 使用示例 getUser() // 触发 ID is required 错误 ``` ### 4. 链式操作中的错误传播 Promise 链会自动传递错误到最近的 `catch()`: ```javascript checkPermission() .then(accessData) .then(processData) .catch(error => { // 捕获前面所有步骤的错误 console.error('Operation failed:', error); }); ``` ### 完整示例 ```javascript function simulateAsync(value) { return new Promise((resolve, reject) => { setTimeout(() => { if (value < 0) { reject(new Error('Value cannot be negative')); // 方式1: reject } else if (value === 0) { throw new Error('Zero is not allowed'); // 方式2: throw (不推荐在executor内使用) } else { resolve(value * 2); } }, 1000); }); } // 使用 simulateAsync(-5) .then(result => { console.log('Result:', result); if (result > 10) throw new Error('Value too large'); // 方式3: then中throw }) .catch(error => console.error('Caught error:', error.message)); // 输出: Caught error: Value cannot be negative ``` ### 最佳实践 1. **优先使用 `reject()`** 在 Promise 执行器内始终使用 `reject()` 而不是 `throw` 2. **错误类型化** 使用 `new Error('message')` 而不是字符串,保留堆栈信息 ```javascript // 推荐 reject(new ValidationError('Invalid email')); // 不推荐 reject('Invalid email'); ``` 3. **全局错误处理** 添加全局未捕获错误处理: ```javascript // 浏览器环境 window.addEventListener('unhandledrejection', event => { console.error('Unhandled rejection:', event.reason); }); ``` 4. **finally 清理** 使用 `finally()` 进行资源清理: ```javascript loadResource() .then(process) .catch(handleError) .finally(() => cleanUp()); // 无论成功失败都会执行 ``` [^1] [^2] [^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值