当前位置:网站首页>Promise学习(一)Promise是什么?怎么用?回调地狱怎么解决?
Promise学习(一)Promise是什么?怎么用?回调地狱怎么解决?
2022-08-01 10:21:00 【對不起该用户已成仙】
目录
前言
Promise是什么
Promise概述
Promise 是异步编程的一种解决方案,它是ES6 规范的一门新的技术。
- 从语法上讲,promise是一个对象、也是一个构造函数,从它可以获取异步操作的消息。
- 从本意上讲,它也是承诺,承诺会给你一个结果。
- 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值。
Promise的状态
promise实例有三种状态:
- 异步操作未完成(
pending) - 异步操作成功(
resolved/fulfilled) - 异步操作失败(
rejected)
promise 的状态改变:
pending变为resolved/fulfilledpending变为rejected
状态只能改变一次,一旦改变,就不会再变,且都会有一个结果数据,成功的结果数据一般称为 value, 失败的结果数据一般称为 reason
promise的基本流程

代码展示如下,我们只调取了成功的回调,可以得到最后的结果为 ‘okk’
const p = new Promise((resolve, reject) => {
// 异步语句 延时器
setTimeout(() => {
if ('异步操作成功') {
// 成功状态
resolve('okk');
} else {
// 失败状态
reject('err');
}
},1000);
});
// 调用 then 方法 指定回调
p.then(value => {
// 成功回调
console.log(value);
}, reason => {
// 失败回调
console.log(reason);
});
这里也要说一下改变 promise 状态和指定回调函数执行顺序,后续博客会系统的更新该部分问题,这里我们只需要知道只有当状态改变后才能得到数据,也就是说,当前状态由
pending变为resolved/fulfilled后,才能得到成功的回调数据 ‘okk’ 。
为什么要用Promise
1. 指定回调函数的方式更加灵活
旧的: 必须在启动异步任务前指定
promise : 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)
2. 支持链式调用, 可以解决回调地狱问题
2.1 什么是回调地狱
回调地狱是指:多层嵌套函数,函数的返回值是下一个函数的执行条件。
setTimeout(() => {
console.log('1');
setTimeout(() => {
console.log('2');
setTimeout(() => {
console.log('3');
}, 1000);
}, 2000);
}, 3000);

回调函数中嵌套回调函数的情况就叫做回调地狱,可以看到,上面嵌套了三层延时器(也是一种回调函数),最后每隔一秒一次输出‘1’,‘2’,‘3’
回调地狱的缺点是不便于阅读 不便于异常处理
2.2 原生Promise链式解决方案
const test = n => {
return new Promise((resolve, reject) => {
// 异步任务
setTimeout(() => {
resolve(n);
}, 1000);
});
}
test(1).then(data => {
console.log(data);
return test(2);
}).then(data => {
console.log(data);
return test(3);
}).then(data => {
console.log(data);
}).catch(data => {
console.log(data);
});
2.3 Promise的async/await解决(终极方案)
const test1 = n => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(n)
}, 1000);
});
}
const test = async () => {
console.log(await test1(1));
console.log(await test1(2));
console.log(await test1(3));
}
test();
Promise 的几个常用小案例
Promise 封装 fs 读取文件操作
/** * 封装一个函数 mineReadFile 读取文件内容 * 参数: path 文件路径 * 返回: promise 对象 */
let mineReadFile = (path) => {
return new Promise ((resolve, reject) => {
//读取文件
require('fs').readFile(path, (err, data) => {
// 判断
if (err) reject(err);
// 成功
resolve(data);
});
});
}
mineReadFile('./resource/content.txt').then(value => {
// 输出文件内容(成功)
console.log(value.toString());
}, reason => {
console.log(reason);
});
Promise 的 util.promisify 方法
可以将函数直接变成promise的封装方式,不用再去手动封装
//引入 util 模块
const util = require('util');
//引入 fs 模块
const fs = require('fs');
//返回一个新的函数
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./resource/content.txt').then(value=>{
console.log(value.toString());
}, reason=> {
console.log(reason);
});
Promise 封装 Ajax 异步请求
/** * 封装一个函数 sendAJAX 发送 GET AJAX 请求 * 参数 URL * 返回结果 Promise 对象 */
const sendAJAX = (url) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.open('GET', url);
xhr.send();
// 处理结果
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
// 判断成功
if(xhr.status >= 200 && xhr.status < 300) {
// 成功的结果为响应体
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
});
}
sendAJAX('https://pagead2.googlesyndication.com/getconfig/sodar?sv=200&tid=gda&tv=r20220718&st=env').then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
本文中使用到的一些Promise的API(如 then, catch等方法)见下一篇博客
Promise学习(二)一篇文章带你快速了解Promise中的常用API
Authors: min
时间: 2022年7月24日
边栏推荐
- 浏览器快捷键大全
- Quantify daily work metrics
- 【钛晨报】国家统计局:7月制造业PMI为49%;玖富旗下理财产品涉嫌欺诈,涉及390亿元;国内航线机票燃油附加费8月5日0时起下调
- ASP.NET Core 6 Framework Revealing Instance Demonstration [30]: Develop REST API with Routing
- Batch大小不一定是2的n次幂!ML资深学者最新结论
- 小程序毕设作品之微信美食菜谱小程序毕业设计成品(1)开发概要
- C language game - minesweeper
- Small application project works WeChat gourmet recipes applet graduation design of finished product (1) the development profile
- Mini Program Graduation Works WeChat Food Recipes Mini Program Graduation Design Finished Products (4) Opening Report
- The first experience of Shengsi large model experience platform——Take the small model LeNet as an example
猜你喜欢

WPF 截图控件之绘制箭头(五)「仿微信」

【软件架构模式】MVVM模式和MVC模式区别

Endorsed in 2022 years inventory | product base, science and technology, guangzhou automobile group striding forward

招聘随想2022
![[Software Architecture Mode] The difference between MVVM mode and MVC mode](/img/37/8470ff9267752d4ca26a6b54ec0b50.png)
[Software Architecture Mode] The difference between MVVM mode and MVC mode

Google Earth Engine APP——15行代码搞定一个inspector高程监测APP

Mysql index related knowledge review one

阿里腾讯面试一二

Qt supports HEIC/HEIF format images

Mini Program Graduation Works WeChat Food Recipes Mini Program Graduation Design Finished Products (4) Opening Report
随机推荐
Introduction to STM32 development Introduce IIC bus, read and write AT24C02 (EEPROM) (using analog timing)
关于#SQL#的问题,如何解决?
Golang内存分析工具gctrace和pprof实战
将本地项目推送到远程仓库
Pve delete virtual machine "for a collection"
July 31, 2022 -- Take your first steps with C# -- Use C# to create readable code with conventions, spaces, and comments
Google Earth Engine APP——15行代码搞定一个inspector高程监测APP
Taobao commodity details and details on taobao, senior upgrade version of the API
周鸿祎称微软抄袭 360 安全模式后发文否认;英特尔CEO基辛格回应市值被AMD超越:股价下跌是咎由自取|极客头条
Dataset之mpg:mpg数据集的简介、下载、使用方法之详细攻略
InputStream转成String
什么是步进电机?40张图带你了解!
redis
Introduction to data warehouse layering (real-time data warehouse architecture)
[Cloud Residency Co-Creation] Huawei Cloud Global Scheduling Technology and Practice of Distributed Technology
Change Servlet project to SSM project
.NET性能优化-使用SourceGenerator-Logger记录日志
小程序毕设作品之微信美食菜谱小程序毕业设计成品(2)小程序功能
Enterprise WeChat group: robot timing reminder function database configuration
STM32 personal notes - program run and fly