一点对Promise的理解与总结
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10959411.html,多谢,=。=~
axios用多了就开始疑惑它里面到底是个啥,虽然总被告知它就是基于ajax的封装,但掐指一算,事情应该没这么简单,于是开始深挖,挖着挖着就挖到了Promise。毕竟axios的官方描述是这样的:Promise based HTTP client for browser and node.js。而axios其中一个特点就是Supports the Promise API,以前只知道promise是一种替代层层回调的解决方案,但现在看来我认为很有必要详细的研究一下。
背景
在JavaScript的世界中,所有代码都是单线程执行的。该特性导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行(否则容易发生阻塞)。异步执行可以用回调函数实现,该方式会在将来的某个时间点触发一个函数调用(回调)。但异步执行中的回调并不利于代码复用,例如:
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
return success(request.responseText);
} else {
return fail(request.status);
}
}
}
但如果是这样的链式写法就会好很多(先统一执行AJAX逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用success函数或fail函数):
var ajax = ajaxGet('http://...');
ajax.ifSuccess(success)
.ifFail(fail);
什么是Promise?
上述“承诺将来会执行”的对象在JavaScript中称为Promise对象,它有各种开源实现,但后面ES6将其写进了语言标准,统一了用法,原生提供了Promise对象,由浏览器直接支持。
Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。
Promise是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
ES6规定,Promise对象是一个构造函数,用来生成Promise实例:
var promise = new Promise(function(resolve, reject) {
// ... some code if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
resolve:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去;
Promise实例生成以后,可以用then方法、catch方法分别指定Resolved状态和Rejected状态的回调函数:
// Promise测试(then、catch)
new Promise(function(resolve,reject) {
let num = Math.random() * 2;
console.log("产生的随机数为:" + num);
setTimeout(function () {
if(num < 1) {
console.log("即将执行成功");
resolve("200 OK");
} else {
console.log("即将执行失败");
reject("失败的原因是num为:" + num);
}
}, num * 1000);
}).then(function(r) {
console.log("then:" + r);
}).catch(function(j) {
console.log("catch:" + j);
});
PS:只用then也可以代替上述效果,因为then可以接受两个回调函数作为参数,第二个参数可选。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Rejected时调用:
promise.then(function(value) {
// success
}, function(error) {
// failure
});
链式多任务串行
有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。要串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码,而使用Promise则可以采用链式写法:job1.then(job2).then(job3).catch(handleError)
// Promise测试(多任务串行执行)
var p = new Promise(function (resolve, reject) {
console.log("resolve开始");
resolve(8);
}); function multi(param) {
return new Promise(function(resolve, reject) {
console.log("计算" + param + "*" + param + ":");
setTimeout(resolve, 1500, param * param);
});
}; function add(param) {
return new Promise(function(resolve, reject) {
console.log("计算" + param + "+" + param + ":");
setTimeout(resolve, 1500, param + param);
});
}; p.then(multi).then(add).then(multi).then(function(param){
console.log("得到最终的值为:" + param);
});
Promise.all()实现多任务并行
一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是需要并行执行的,用Promise.all()实现如下:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
Promise.race()实现多任务赛跑
有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可,其他任务的结果会被丢弃。这种情况下,用Promise.race()实现:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
参考资料
Promise:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544
ECMAScript 6 Promise对象:https://www.w3cschool.cn/ecmascript/3uge1q5v.html
一点对Promise的理解与总结的更多相关文章
- 「每日一题」面试官问你对Promise的理解?可能是需要你能手动实现各个特性
关注「松宝写代码」,精选好文,每日一题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目类 ...
- promise的理解和使用
1. Promise是什么 1.1 promise 的理解 1. 抽象表达: Promise 是 JS 中进行异步编程的新的解决方案(旧的是纯回调形式) 2. 具体表达: (1)从语法上说:Promi ...
- 一点关于this的理解
关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...
- promise的理解
为什么会有promise,他的作用是什么? promise主要是为了解决js中多个异步回调难以维护和控制的问题. 什么是promise? 从图中,我们可以看出,Promise是一个函数,这个函数上有在 ...
- promise的理解和应用
老铁们,我又满血复活了,今天我准备来吹一波我对promise,如有错吴请直接指出,明白了吗?话不多说开始吧 首先我们需要知道啥叫promise,我问了问大佬,他说这个东西是 异步操作的同步代码(but ...
- 谈谈你对Promise的理解
一.Promise是什么? 理解 抽象表达: Promise 是一门新的技术(ES6 规范) Promise 是 JS 中进行异步编程的新解决方案(备注:旧方案是单纯使用回调函数) 具体表达: 从语法 ...
- 对Promise的理解?
ES6原生提供了promise对象 所谓Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通过是一个异步操作),并且这个事件提供统一的API,可供进一步处理 P ...
- 谈谈我对Promise的理解
一.Promise是什么? Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大. ES6 将其写进了语言标准,统一了用法,原生提供了Pr ...
- 深入理解promise
如今promise大行其道,关于异步方面的几乎都有它的影子,新的fetch api返回的是promise对象,generator中的yield后面一般也会跟promise对象,async的await后 ...
随机推荐
- Windows下git的安装与配置
表示git安装成功.
- phpstudy配置php7.1.11
php7.1.11下载地址 http://windows.php.net/download/ 下载之后,解压. 重名的为php-7.1.11-nts 移动到phpStudy的php目录下 然后重启ph ...
- HDU 1506【单调栈】
思路: 转化成对于某一位置为最小值求向两边最远>=他的位置,用单调栈就能轻易完成. 那么ans=(left+right)*h[i]; 维护单调递增还是递减呢? 我们能很快反应到,一旦碰到一个比他 ...
- opencv多版本安装
使用命令查看当前的opencv版本: pkg-config --modversion opencv 自带的是opencv-2.4.9 安装opencv3.1 安装opencv的依赖项 sudo apt ...
- 洛谷P3688/uoj#291. [ZJOI2017]树状数组
传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...
- 剑指Offer的学习笔记(C#篇)-- 二进制中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 一 . 解题思路 新颖的解法,使得该题目运用到了二进制的位运算符.先了解一下位运算符! 此题便很好的发挥了位运算符& ...
- Java 环境问题汇总
准备java环境时,需要设置JAVA_HOME 和 Path , CLASSPATH 环境变量,它们可以是用户变量,也可以是系统变量. 注意: 系统变量的路径排在用户变量之前. 其中,Windows操 ...
- CreateJS介绍-了解CreateJS
1.CreateJS 一款HTML5游戏开发引擎 CreateJS 是一套可以构建丰富交互体验的 HTML5 游戏的开源工具包,旨在降低 HTML5 项目的开发难度和成本,让开发者以熟悉的方式打造更具 ...
- Unity 打包PC和安卓的路径注意事项
if UNITY_STANDALONE_WIN || UNITY_EDITOR return Application.persistentDataPath + "/LocalData&quo ...
- python进阶07 MySQL
python进阶07 MySQL 一.MySQL基本结构 1.认识MySQL #MySQL不是数据库,它是数据库管理软件 #MySQL如何组织数据 #如何进入MySQL数据库 #其他注意事项 #以表格 ...