[javascript核心-04]彻底弄懂Promise异步编程

这篇具有很好参考价值的文章主要介绍了[javascript核心-04]彻底弄懂Promise异步编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. Promise 的使用

本文github地址:JavaScript_Interview_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士

1.1. 快速上手

01快手上手.js

const promise = new Promise((resolve,reject)=>{
    // 此处的代码同步立即执行
    resolve('ok'); // pending状态
});

// 状态不可更改
promise.then((res)=>{
    console.log(res); // fulfilled/resolved 状态
},(err)=>{
    console.log(res); // rejected状态
})

02.若传入的是另一个promise对象,则状态由传入的promise对象决定

// 若传入的是另一个promise对象,则状态由传入的promise对象决定 

const promise = new Promise((resolve, reject)=>{
    reject('no');
})

new Promise((resolve, reject)=>{
    resolve(promise) // 传入的promise决定状态
}).then((res)=>{
    console.log(res,'yes');
},(err)=>{
    console.log(err, 'no');  // 执行
})

03.若传入了一个实现了 then 方法的对象,则执行该then方法且由此方法决定状态

// 若传入了一个实现了 then 方法的对象,则执行该then方法且由此方法决定状态

const testObj = {
    then : function(resolve, reject){
        resolve('ok');
    }
}

new Promise((resolve, reject)=>{
    resolve(testObj);
}).then((res)=>{
    console.log('res', res); // 执行
}, (err)=>{
    console.log('err', err);
})
1.2. then 方法

then方法返回一个新的 Promise 对象;

then方法返回一个 Promise,如果直接在then方法里返回一个普通对象,则会将其包裹为一个 Promise 对象;

4.js

const promise = new Promise((resolve,reject)=>{
    resolve('ok')
});

promise.then((res)=>{
    return 'new';
}).then(res=>{
    console.log('new',res) // new new
})


/*执行结果
old1 ok
new new
old2 undefined
*/

无返回值时,默认返回undefined

5.js

const promise = new Promise((resolve,reject)=>{
    resolve('ok')
});

promise.then((res)=>{
    console.log('old1',res) // old1 ok
    // 无返回值默认返回 undefined, 作为新返回的 Promise对象resolve值
}).then(res=>{
    console.log('old2',res) // old2 undefined
})

//old1 ok
//old2 undefined

若返回 Promise 时,将 Promise用 Promise 进行包裹,即返回了一个参数为 Promise 对象的 Promise;

6.js

const promise = new Promise((resolve,reject)=>{
    resolve('ok')
});

// then方法返回 Promise 时,将 Promise用 Promise 进行包裹,即返回了一个参数为 Promise 对象的 Promise
promise.then((res)=>{
    return new Promise((resolve, reject)=>{
        resolve('return promise')
    })
}).then(res=>{
    console.log(res); // return promise
})

// return promise

若传入了一个实现了 then 方法的对象,将 Promise用 Promise 进行包裹,执行该then方法且由此方法决定状态;

7.js

const promise = new Promise((resolve,reject)=>{
    resolve('ok')
});

promise.then((res)=>{
    return obj = {
        then: function(){
            console.log('thenable');
        }
    }
}).then(res=>{
    console.log(res);
});

// thenable
1.3. catch方法与异常捕获与错误

用then方法的第二个回调函数捕获错误

08.js

const promise = new Promise((resolve, reject)=>{
    throw new Error('示例抛出异常')
});

promise.then(res, err=>{
    console.log(err);
});

catch捕获错误

09.js

const promise = new Promise((resolve, reject)=>{
    throw new Error('示例抛出异常')
});

promise.catch(err=>{
    console.log(err);
});

链式调用中,catch优先捕获的是第一个Promise 对象抛出的异常

10.js

const promise = new Promise((resolve, reject)=>{
    throw new Error('示例抛出异常')
});

promise.then(res =>{
    return new Promise((resolve, reject)=>{
        throw new Error('then方法返回的 Promise 错误')
    })
}).catch(err=>{ // 捕获的是第一个Promise 对象抛出的异常
    console.log(err); // Error: 示例抛出异常
})

若第一个 Promise 没有抛出异常,则捕获then方法返回的 Promise 对象的异常

11.js

const promise = new Promise((resolve, reject)=>{
    resolve('ok')
});

promise.then(res =>{
    return new Promise((resolve, reject)=>{
        throw new Error('then方法返回的 Promise 错误')
    })
}).catch(err=>{ // 捕获的是then方法返回的Promise 对象抛出的异常
    console.log(err); // Error: 示例抛出异常
})

catch可以捕获reject异常

12.js

const promise = new Promise((resolve, reject)=>{
    reject('err')
});

promise.then(res =>{
    return new Promise((resolve, reject)=>{
        throw new Error('then方法返回的 Promise 错误')
    })
}).catch(err=>{ // 捕获的是第一个Promise 的reject信息
    console.log(err); // err
})

13.js

如果catch是非链式调用,则then方法需要进行自己的错误捕获,与后面catch的错误捕获是独立的

const promise = new Promise((resolve, reject)=>{
    reject('err')
});

promise.then(res=>{
    console.log(res)
},err=>{
    console.log(err,'then中错误捕获')
})

promise.catch(err=>{
    console.log(err, '单独catch捕获')
})

/*
err then中错误捕获
err 单独catch捕获
*/

catch方法也是返回一个 Promise 对象

14.js

const promise = new Promise((resolve, reject)=>{
    reject('err')
});

// catch方法也是返回一个 Promise 对象
// 如果不是抛出异常,则后面执行then
promise.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err, '第一个catch')
    return err
}).then(res=>{
    console.log(res,'第二个then')
}).catch(err=>{
    console.log(err)
})

/*
err 第一个catch
err 第二个then
*/

若catch方法返回错误,会被后面的catch捕获

15.js

const promise = new Promise((resolve, reject)=>{
    reject('err')
});

// catch方法返回错误,会被后面的catch捕获
promise.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err, '第一个catch')
    return new Error('错误')
}).then(res=>{
    console.log(res,'第二个then')
}).catch(err=>{
    console.log(err)
})

/*
err 第一个catch
Error: 错误
*/
1.4. finally,最后一定会执行

16.js

const promise = new Promise((resolve, reject)=>{
    reject('err')
});

promise.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)
}).finally(()=>{
    console.log('end')
})
1.5. 类方法-Promise.resolve()

将一个对象直接转为promise对象

17.js

const promise = new Promise((resolve, reject)=>{
    resolve({name:'flten'});
});

promise.then(res=>{
    console.log(res); // { name: 'flten' }
})

const promise2 = Promise.resolve({name:'flten'});

promise2.then(res=>{
    console.log(res); // { name: 'flten' }
})
1.6. 类方法-Promise.reject()

直接返回一个 reject 状态的 Promise 对象

18.js

const promise =  Promise.reject('no');

promise.then(res=>{
    console.log(res);
}).catch(err=>{
    console.log(err); // no
})
1.7. 类方法-Promise.all()

传入一个 Promise 对象数组,按数组顺序返回数据

19.js

const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(1)
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(2)
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

Promise.all([promise1, promise2, promise3]).then(res=>{
    console.log(res) // [ 1, 2, 3 ]
})

但其中一个 Promise 对象变成reject状态,则新的 Promise 立即变为reject状态

// 20.js

const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(1)
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

// 其中一个 Promise 对象变成reject状态,则新的 Promise 立即变为reject状态
Promise.all([promise1, promise2, promise3]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err) // err
})
1.8. 类方法-Promise.allSettled()

在即使有 reject 状态的情况下,仍然返回全部结果

// 21.js
const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(1)
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

Promise.allSettled([promise1, promise2, promise3]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err) 
})

/*
[
  { status: 'fulfilled', value: 1 },
  { status: 'rejected', reason: 'err' },
  { status: 'fulfilled', value: 3 }
]
*/
1.9. 类方法-Promise.race()

返回最先执行结束的Promise

// 22.js
const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(1)
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

Promise.race([promise1,promise2,promise3]).then(res=>{
    console.log(res) // 1
})

如果第一个执行结束的是返回 reject 状态,同样返回 reject 的结果

// 23.js
const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err1')
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

Promise.race([promise1,promise2,promise3]).then(res=>{
    console.log('res',res)
}).catch(err=>{
    console.log('err',err) // err err1
})
1.10. 类方法-Promise.any()

得到一个状态为 fulfilled 之后才会结束,不会因为第一个返回的状态为 reject 而直接结束

// 24.js
const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err1')
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
})

// 有一个状态为 fulfilled 之后才会结束
Promise.any([promise1,promise2,promise3]).then(res=>{
    console.log(res) // 3
}).catch(err=>{
    console.log(err) 
})

若全为 reject , 也会等到全部 Promise 执行都返回reject

// 25.js
const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err1')
    },1000)
})

const promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err2')
    },2000)
})

const promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('err3')
    },3000)
})

// 若全为 reject , 也会等到全部 Promise 执行都返回reject
Promise.any([promise1,promise2,promise3]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err) // AggregateError: All promises were rejected
    console.log(err.errors) // (3) ['err1', 'err2', 'err3']
})

本文github地址:JavaScript_Interview_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士文章来源地址https://www.toymoban.com/news/detail-473356.html

到了这里,关于[javascript核心-04]彻底弄懂Promise异步编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端异步编程 —— Promise对象

    在前端编程中,处理一些简短、快速的操作,在主线程中就可以完成。 但是,在处理一些耗时比较长以至于比较明显的事情,比如读取一个大文件或者发出一个网络请求,就需要异步编程来实现,以避免只用主线程时造成页面一时无法响应的事情。 以发送网络请求为例,在

    2024年02月08日
    浏览(36)
  • JS中的异步编程与Promise

    在了解JavaScript的异步机制之前,我们首先需要理解JavaScript是一种单线程语言。单线程就意味着所有的任务需要按照顺序一次执行,如果前一个任务没有完成,后一个任务就无法开始。这个特性在执行大量或耗时任务时可能会导致阻塞或者界面卡死,这显然是不可取的。 为了

    2024年02月08日
    浏览(34)
  • promise及异步编程async await

    ECMAScript 6 新增了正式的 Promise(期约)引用类型,支持优雅地定义和组织异步逻辑。接下来几个版本增加了使用 async 和 await 定义异步函数的机制 JavaScript 是单线程事件循环模型。异步行为是为了优化因计算量大而时间长的操作,只要你不想为等待某个异步操作而阻塞

    2024年02月04日
    浏览(29)
  • 前端面试:【异步编程】Callback、Promise和Async/Await

    嗨,亲爱的JavaScript探险家!在JavaScript开发的旅程中,你会经常遇到异步编程的需求。为了处理异步操作,JavaScript提供了多种机制,包括Callbacks、Promises和Async/Await。本文将深入介绍这些机制,让你能够更好地处理异步任务。 1. Callbacks:传统的异步方式 Callbacks是JavaScript中最早

    2024年02月11日
    浏览(33)
  • 前端异步编程全套:xmlhttprequest > ajax > promise > async/await

    同步与异步区别 同步:按顺序,依次执行,向服务器发送请求--客户端做其他操作 异步:分别执行,向服务器发送请求==同时执行其他操作 原生xmlhttprequest 四步骤 创建ajax对象 设定数据的传输方式(get、post),打开连接open() 获得响应数据 属性 描述 onreadystatechange 当readysta

    2024年02月01日
    浏览(34)
  • [javascript核心-09] 彻底解决js中的类型检测方案

    typeof 基于数据类型的值(二进制)进行检测 返回结果为字符串 typeof NaN 结果为 number typeof null 结果为 Object .对象存储以 000 开头,而 null 也是如此。 typeof 不能细分对象,结果都是 Object typeof function(){} 结果为 function instanceof 检测某个构造函数是否出现在某实例的原型链上 返回结

    2024年02月16日
    浏览(40)
  • 【angular教程240111】08异步数据流编程与angular :promise,Rxjs6.x

    【angular教程240111】08异步数据流编程与angular :promise,Rxjs6.x 三级目录 异步与 Rxjs6.x异步数据流编程-Angular Rxjs快速入门 一、 Rxjs介绍 二、 Promise和RxJS 处理异步对比 三、 Rxjs unsubscribe取消订阅 四、 Rxjs 订阅后多次执行 五、 Angualr6.x之前使用Rxjs的工具函数map filter 六、 Angualr6

    2024年02月02日
    浏览(29)
  • web前端框架Javascript之JavaScript 异步编程史

    早期的 Web 应用中,与后台进行交互时,需要进行 form 表单的提交,然后在页面刷新后给用户反馈结果。在页面刷新过程中,后台会重新返回一段 HTML 代码,这段 HTML 中的大部分内容与之前页面基本相同,这势必造成了流量的浪费,而且一来一回也延长了页面的响应时间,总

    2024年02月14日
    浏览(38)
  • JavaScript 异步编程解决方案-上篇

    1、JavaScript 异步编程 1、传统的方案 :JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理 场景:fs 文件操作 数据库操作 AJAX 定时器 eg: 1、setTimeout 函数

    2024年02月01日
    浏览(29)
  • JavaScript 异步编程解决方案-中篇

    1.Promise 构造函数:new Promise(executor) Promise() 只能通过 new 运算符来构造。如果尝试在没有使用 new 的情况下调用它,会抛出 TypeError 异常。 1.executor 执行器函数:(resolve,reject)={} 2.resolve 函数:内部定义成功时候调用values={} 3.reject 函数:内部定义失败时候调用error={} 备注:e

    2024年01月23日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包