当前位置:网站首页>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
/fulfilled
pending
变为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日
边栏推荐
猜你喜欢
基于CAP组件实现补偿事务与消息幂等性
AI篮球裁判火了,走步算得特别准,就问哈登慌不慌
DBPack SQL Tracing 功能及数据加密功能详解
MacOS下postgresql(pgsql)数据库密码为什么不需要填写或可以乱填写
周鸿祎称微软抄袭 360 安全模式后发文否认;英特尔CEO基辛格回应市值被AMD超越:股价下跌是咎由自取|极客头条
Enterprise WeChat group: robot timing reminder function database configuration
已解决(pip安装库报错)Consider using the-- user option or check the permissions.
What's up with VS "Cannot find or open PDB file"?How to solve
Change Servlet project to SSM project
WPF 截图控件之绘制箭头(五)「仿微信」
随机推荐
Introduction to STM32 development Introduce IIC bus, read and write AT24C02 (EEPROM) (using analog timing)
notes....
[Software Architecture Mode] The difference between MVVM mode and MVC mode
报告:想学AI的学生数量已涨200%,老师都不够用了
redis
Message queue interview latest finishing (2022)
正则表达式
How to find out hidden computer software (how to clean up the computer software hidden)
.NET性能优化-使用SourceGenerator-Logger记录日志
ASP.NET Core 6 Framework Revealing Instance Demonstration [30]: Develop REST API with Routing
Generate certificates using KeyStore
从零开始Blazor Server(4)--登录系统
如何从完美的智能合约中窃取 1 亿美元
对于小应用来讲,使用哪款数据库比较好?
Introduction to data warehouse layering (real-time data warehouse architecture)
C语言小游戏——扫雷
mysql login in cmd and basic operations of database and table
mysql在cmd的登录及数据库与表的基本操作
深度学习 | MATLAB实现GRU门控循环单元gruLayer参数设定
50.【Application of dynamic two-dimensional array】