再谈promise

promise反复学习总结就会深刻 提高;

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>再谈promise</title> </head> <body> <script type="text/javascript"> /* Promise 出现的原因: 例如ajax【根据第一个网络请求的结果,再去执行第二个网络请求】===> 此时造成回调地狱 后果: 1.代码臃肿 2.可读性差 3.耦合度过高,可维护性差 4.代码复用性差 5.容易滋生 bug 6.只能在回调里处理异常 什么是 Promise?   Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。 promise本身是同步的 promise的回调then/catch是异步的 async/await也是基于 Promise 实现的 async函数内部同步执行,await之间相当于.then。 async函数外部的调用异步执行 传统回调地狱版本: 请求1(function(请求结果1){ 请求2(function(请求结果2){ 请求3(function(请求结果3){ 请求4(function(请求结果4){ 请求5(function(请求结果5){ 请求6(function(请求结果3){ ... }) }) }) }) }) }) promise版本: new Promise(请求1) .then(请求2(请求结果1)) .then(请求3(请求结果2)) .then(请求4(请求结果3)) .then(请求5(请求结果4)) .catch(处理异常(异常信息)) Promise常用的 API Promise.prototype.then() Promise.prototype.finally(): 不管 Promise 对象最后状态如何,都会执行的操作 Promise.all() Promise.allSettled() Promise.race(): Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例 Promise.any(): 该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回 Promise.resolve() Promise.reject(): 返回一个新的 Promise 实例,实例的状态为rejected Promise.try() Promise.prototype.catch() Promise.try就是模拟try代码块,就像promise.catch模拟的是catch代码块 Promise有三种状态, pending , resolved , rejected , 只能从等待态转为其他两种状态; 每次调用then方法,都会返回一个新的promise; promise支持链式调用,内部原理采用的是发布订阅模式; 一定谨记,一个 Promise 对象有三个状态,并且状态一旦改变,便不能再被更改为其他状态!!! */ // 首先初始化一个 Promise 对象,可以通过两种方式创建 Promise构造函数【new Promise()】接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数 // resolve函数的作用是: 将Promise对象的状态从【未完成】变为【成功】(即从 pending => resolved) // reject函数的作用是: 将Promise对象的状态从【未完成】变为【失败】(即从 pending => rejected) function fn(resolve, reject) { console.log('返回promise对象') // resolve(1) } // 方式一 const promise1 = new Promise(fn) console.log(promise1) // Promise {<pending>} 若是fn加上 resolve(1) 则 状态变为 Promise {<fulfilled>: 1} // 方式二 const promise2 = Promise.resolve(fn) console.log(promise2) // Promise {<fulfilled>: ƒ} /*****************Promise.any() 与 Promise.race() 和 Promise.all() 和 Promise.allSettled()********************/ // 只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态 // Promise.any()跟Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束 const q1 = new Promise((resolve, reject) => { reject("失败"); }); const q2 = new Promise((resolve, reject) => { setTimeout(resolve, 300, "后成功"); }); const q3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, "先成功"); }); const q4 = new Promise((resolve, reject) => { setTimeout(resolve, 500, "最后成功"); }); Promise.any([q1, q2, q3]).then((res) => { console.log(res); // 先成功 }) Promise.race([q2, q3, q4]).then((res) => { console.log(res); // 先成功 }) Promise.all([q2, q3, q4]).then((res) => { console.log(res); // ["后成功", "先成功", "最后成功"] }).catch(e => console.log(e)); const resolved = Promise.resolve(1); const rejected = Promise.reject(-1); const allSettledPromise = Promise.allSettled([resolved, rejected]); allSettledPromise.then(function(results) { console.log(results); // [{status: 'fulfilled', value: 1},{status: 'rejected', reason: -1}] }); // 总结 // Promise.any()即使第一个返回的 promise 是失败的,Promise.any() 依然使用第一个成功状态的 promise 来返回 // 这与使用首个(无论 rejected 还是 fullfiled)promise 来返回的 Promise.race() 相反 // Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝 // Promise.all(iterable) 方法返回一个 Promise 实例只要有其中一个promise实例是rejected,就会直接走catch方法,并且catch中只会返回第一个变成rejected的promise的错误 // Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理 // Promise.all()无法确定所有请求都结束 Promise.allSettled()就很容易 /****************************Promise.resolve()**************************************/ // 需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用 const r1 = Promise.resolve('aa') console.log(r1, 'r1') // Promise {<fulfilled>: "aa"} "r1" // 等价于 const r2 = new Promise(resolve => resolve('aa')) console.log(r2, 'r2') // Promise {<fulfilled>: "aa"} "r2" // Promise.resolve()参数的四种情况 // 1.参数是一个 Promise 实例 // 如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例 // 2.参数是一个thenable对象 let thenable = { then: function(resolve, reject) { resolve(666); } }; let promise = Promise.resolve(thenable); promise.then(function(res) { console.log(res, 'res'); // 666 }); // 3.参数不是具有then()方法的对象,或根本就不是对象 const p = Promise.resolve('Hello world'); p.then(function(res) { console.log(res) // Hello world }); // 4.不带有任何参数 setTimeout(function() { console.log('3'); }, 0); Promise.resolve().then(function() { console.log('2'); }); console.log('1'); // 输出的顺序为 1 2 3 /****************************Promise.reject()**************************************/ // Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数 const p1 = Promise.reject('出错了'); // Uncaught (in promise) 出错了 console.log(p1, 'p1') // Promise {<rejected>: "出错了"} "p1" // 等同于 const p2 = new Promise((resolve, reject) => reject('出错了')) p2.then(null, function(r) { console.log(r, 'r') // 出错了 r }); // 异步转同步 // 1.通过回调函数【回调函数就是将一个函数当作另一个主函数的参数来使用的函数】 function test2() { console.log('执行了test2'); } function test1(cb) { //(主函数) console.log('执行了test1'); setTimeout(function() { cb(); }, 1000); } // 执行 test1(test2); // 2 async-await async/await的作用就是使异步操作以同步的方式去执行 // 一般情况下,async与await配合使用才能使异步操作同步化,await就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行 async function test() { return '异步转同步' } console.log(test()); //Promise { '异步转同步' } test().then(res => { console.log(res, 'res'); // 异步转同步 'res' }) function fn1() { return new Promise(resolve => { setTimeout(function() { msg = 'wait me 3000'; resolve(msg) }, 3000); }); } async function fn2() { var result = await fn1(); console.log(result); } fn2(); // 使用Promise function fn3() { return new Promise(function(resolve, reject) { setTimeout(function() { msg = 'wait me 3000'; resolve(msg); }, 3000); }) } fn3().then(data => { console.log(data) }) </script> </body> </html>

 自己整理,请勿随意转载!!!!


__EOF__

本文作者蓝色帅-橙子哥
本文链接https://www.cnblogs.com/lhl66/p/14450217.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   鱼樱前端  阅读(122)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2018-02-26 css选择器的对比样式代码精简
2018-02-26 css定位position属性深究
 
往后余生 - 王贰浪
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.
  1. 1 往后余生 王贰浪
  2. 2 拂雪 不才
  3. 3 我的一个道姑朋友 洛尘鞅
  4. 4 大田后生仔 王雨萌
点击右上角即可分享
微信分享提示