Promise API :new Promise(),prototype.then,prototype.catch,resolve,reject,all,race

本文详细讲解了Promise构造函数、executor、then与catch方法的工作原理,重点阐述了then链式调用和错误穿透,并介绍了Promise.resolve和Promise.reject的使用。通过实例解析了Promise.all和Promise.race的区别,适合理解Promise在异步编程中的关键作用。

1.

Promise构造函数:new Promise(executor){}

 executor函数:是同步执行的,(resolve,reject)=>{}

 resolve函数:调用resolve将Promise实例内部状态改为成功(fulfilled)

 reject函数:调用reject将Promise实例内部状态改为成功(rejected)

 2.

Promise.prototype.then方法:Promise实例.then(onFulfilled,onRejected)

 onFulfilled:成功的回调函数(value)=>{}

 onRejected:失败的回调函数(reason)=>{}

特别注意(难点):then方法会返回一个新的Promise实例对象

3.

Promise.prototype.catch方法:Promise实例.catch(onRejected)

 onRejected:失败的回调函数(reason)=>{}

 说明:catch方法是then方法的语法糖,相当于:then(undefiend,onRejected)

4.

 Promise.resolve方法:Promise.resolve(value)

 说明:用于快速返回一个状态为fulfilled或rejected的Promise实例对象

 备注:value的值可能是:(1)非Promise值  (2)Promise值

5.

 Promise.reject方法:Promise.reject(reason)

 说明:用于快速返回一个状态必为rejected的Promise实例对象

6.

 Promise.all方法:Promise.all(promiseArr)

 promiseArr:包含n个Promise实例的数组

 说明:返回一个新的Promise实例,只有所有的promise都成功才成功,只要有一个失败就直接失败

7.

 Promise.race方法:Promise.race(promiseArr)

 promiseArr:包含n个Promise实例的数组

 说明:返回一个新的Promise实例,成功还是失败?,已最先出结果的Promise为准

视频解析:16_Promise.all与Promise.race_哔哩哔哩_bilibili

Promise实例.then()链式调用,中段Promise链,Promise错误穿透.catch()_Allen 赵奇隆的博客-优快云博客

<think>我们正在讨论JavaScriptPromise的pending状态。根据引用[3],Promise有三种状态:pending(进行中)、resolved(已成功)和rejected(已失败)。初始状态是pending,当调用resolve()时状态变为resolved,调用reject()时变为rejected。用户的问题是想理解Promise状态为pending的原因以及如何处理。结合引用中的信息,我们可以分析如下:###原因分析1.**未调用resolvereject**:如果创建Promise时,传入的函数(执行器函数)内部没有调用resolvereject,那么Promise就会一直保持pending状态。例如:```javascriptletp=newPromise((resolve,reject)=>{//没有调用resolvereject});console.log(p);//状态为pending```2.**异步操作未完成**:如果执行器函数中有异步操作(如setTimeout、网络请求等),并且在异步操作完成时才调用resolvereject,那么在异步操作完成之前,Promise的状态都是pending。例如:```javascriptletp=newPromise((resolve)=>{setTimeout(()=>resolve("完成"),1000);});//在1秒内,p的状态都是pending```3.**使用race方法检测状态**:引用[1]中提供了一种检测Promise状态的方法,通过Promise.race来比较。如果返回'pending',说明原始Promise仍然处于pending状态。###解决方法1.**确保调用resolvereject**:在Promise的执行器函数中,无论操作是同步还是异步,最终都要调用resolvereject来改变状态。避免遗漏。2.**处理异步操作**:对于异步操作,需要等待异步操作完成后再改变状态。确保在异步回调中调用resolvereject。3.**使用async/await或then方法**:当使用一个返回Promise的函数时,我们可以使用then方法或async/await来等待Promise状态改变。例如:```javascriptasyncfunctionfetchData(){try{letdata=awaitp;//等待直到p的状态不是pendingconsole.log(data);}catch(error){console.error(error);}}```或者```javascriptp.then(data=>{console.log(data);}).catch(error=>{console.error(error);});```4.**避免长时间pending**:如果某个Promise长时间处于pending状态,可能是由于操作本身耗时很长,或者出现了逻辑错误(忘记调用resolve/reject)。我们需要检查代码逻辑,确保在适当的时候改变状态。5.**设置超时**:为了防止Promise永久pending,可以设置一个超时机制。例如,使用Promise.race将一个超时Promise和原始Promise竞争:```javascriptfunctionwithTimeout(promise,timeout){lettimeoutPromise=newPromise((_,reject)=>{setTimeout(()=>reject(newError('超时')),timeout);});returnPromise.race([promise,timeoutPromise]);}//使用letp=newPromise(resolve=>{//可能长时间不resolve});withTimeout(p,5000).then(...).catch(...);//5秒超时```###示例根据引用[1]中的代码,我们可以检测一个Promise的状态:```javascriptconstpromiseState=promise=>{consttarget={};returnPromise.race([promise,target]).then(value=>(value===target)?'pending':'fulfilled',()=>'rejected',);}//测试leta=Promise.resolve();letb=Promise.reject();letc=newPromise(()=>{});//既不resolve也不rejectpromiseState(a).then(state=>console.log(state));//fulfilledpromiseState(b).then(state=>console.log(state));//rejectedpromiseState(c).then(state=>console.log(state));//pending```###总结Promise处于pending状态的原因主要是未调用resolve/reject或异步操作未完成。处理方法是确保在适当的时候调用resolve/reject,并使用then/catch或async/await来处理结果,同时可以设置超时避免永久pending。---§§相关问题§§1.如何检测一个Promise对象是否处于pending状态?2.如何避免Promise长时间处于pending状态?3.在异步操作中忘记调用resolve/reject会导致什么问题?4.如何使用Promise.race实现超时控制?5.Promise的状态改变后还能再次改变吗?</think>### JavaScript Promise Pending 状态详解 #### 一、Pending 状态的原因 Promise 处于 pending(进行中)状态的根本原因是**异步操作尚未完成**,具体可分为: 1. **未调用 resolve/reject** ```javascript // 示例:既未调用 resolve 也未调用 reject const pendingPromise = new Promise((resolve, reject) => { // 缺少 resolve() 或 reject() }); ``` 状态将永远保持 pending[^3] 2. **异步操作未完成** ```javascript const asyncOp = new Promise((resolve) => { setTimeout(() => resolve("完成"), 3000); // 3秒内状态为 pending }); ``` 3. **链式调用未终结** ```javascript fetch('/data') .then(response => { // 未返回新值或 Promise // 状态将保持 pending }); ``` #### 二、解决方案 ##### 1. 确保调用 resolve/reject ```javascript // 正确示例 const validPromise = new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve("成功") : reject("失败"); }, 1000); }); ``` ##### 2. 处理异步操作完成状态 使用 `then()`/`catch()` 捕获状态变更: ```javascript asyncOp .then(result => console.log("已完成:", result)) .catch(error => console.error("已拒绝:", error)) .finally(() => console.log("状态已确定")); ``` ##### 3. 检测 pending 状态(引用[1]方案) ```javascript const promiseState = promise => { const target = {}; return Promise.race([promise, target]).then( value => (value === target) ? 'pending' : 'fulfilled', () => 'rejected' ); } // 使用示例 promiseState(asyncOp).then(state => { if(state === 'pending') console.log("操作仍在进行"); }); ``` ##### 4. 超时处理 ```javascript function withTimeout(promise, timeoutMs) { const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('超时')), timeoutMs) ); return Promise.race([promise, timeout]); } // 使用 withTimeout(fetch('/data'), 5000) .catch(err => console.error(err)); // 5秒未完成则超时 ``` #### 三、关键机制 1. **状态单向流动** $$ \text{pending} \xrightarrow{\text{resolve()}} \text{fulfilled} \quad \text{或} \quad \text{pending} \xrightarrow{\text{reject()}} \text{rejected} $$ 状态一旦变更不可逆转[^3] 2. **执行器函数要求** Promise 构造函数**必须接收函数参数**,否则报错(引用[2]): ```javascript new Promise() // TypeError: Promise resolver undefined is not a function ``` #### 四、最佳实践 1. **始终返回终结操作** ```javascript fetch('/data') .then(response => response.json()) .then(data => { // 返回明确值 return { status: 'success', data }; }); ``` 2. **添加超时控制** 关键业务操作建议使用 `Promise.race()` 实现超时限制 3. **避免嵌套陷阱** ```javascript // 错误:嵌套导致内层 promise 状态被忽略 fetch('/a').then(a => { fetch('/b').then(b => a + b); // 未返回 }); // 正确:返回链式调用 fetch('/a') .then(a => fetch('/b').then(b => a + b)); ``` > 当 Promise 保持 pending 时,通常意味着: > 1. 异步操作未完成(正常) > 2. 忘记调用 resolve/reject(需修复) > 3. 未正确处理 promise 链(需检查返回语句) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值