快速入门上手JavaScript中的Promise
当我还是一个小白的时候,我翻了很多关于Promise介绍的文档,我一直没能理解所谓解决异步操作的痛点是什么意思
直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思理解最为简单粗暴
这就是一个承诺,相当于在代码中提供一个在任何时候承诺之后要做什么事的方式,这个承诺可能会兑现也可能无法兑现,当然也可能在兑现的过程中
用这个来替代我们曾经需要写的回调函数,可以避免JavaScript程序中的回调地狱
所以先不去学习的语法,从另一个方式先理解,希望可以帮助你更好的学习或上手Promise
什么是Promise?
Promise是异步编程的一种解决方案,可以替代传统的解决方案,比如回调函数和事件
其在ES6中统一了用法,并提供了原生的Promise对象,Promise对象表示异步操作的最终完成(或失败)及其结果值
作为对象,Promise有以下两个特点:
- 对象的状态不受外界影响
- 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,
 这也是Promise这个名字的由来,它的英语意思就是承诺,表示其他手段无法改变
 
- 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,
- 一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态
- pending:初始状态,不是成功或失败状态;
 - fulfilled(resolved):操作成功完成状态;
 - rejected:操作失败状态
- Promise对象的状态改变,只有两种可能:从- Pending变为- Resolved和从- Pending变为- Rejected,
 只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,
 就算改变已经发生了,你再对- Promise对象添加回调函数,也会立即得到这个结果,
 这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的
 
Promise的创建和用途
- 构造函数接受一个名为executor的函数,此执行函数接受两个f函数参数,resolve和reject。
        new Promise( /* executor */ function(resolve, reject { ... }) );
- Promise通常用于阻塞代码和异步操作,其中包括文件调用,API调用,DB调用,IO调用等等
- 这些异步操作的启动发生在执行函数中,如果异步操作成功,则通过promise的创建者调用resolve()函数返回预期结果,
 同样,如果出现意外错误,则通过调用reject()函数传递错误具体信息
- 由于promise会立即执行,我们无法检查promise的初始状态,所以创建一个需要时间执行的promise最简单的方式就是
 使用setTimeOut()函数,通过浏览器控制台的输出可以直观看到之前所说的状态,以及他的变化过程
	var promiseFir = new Promise(function(resolve, reject) {
		setTimeout(function() {
			resolve({
				message: '与大家分享知识很开心!',
				code: 200
			});
		}, 2000)
	})
	console.log(promiseFir);
	setTimeout(function() {
		console.log(promiseFir);
	}, 2000)
Promise的方法
- 3种原型方法
	// 用一个小故事举例,你是一个上学的孩子,你问你的妈妈要一个电话。她说: 这个月底我要买一部手机
	var momsPromise = new Promise(function(resolve, reject) {
		momsSavings = 20000;  // 因为妈妈没有足够储蓄所以无法买到礼物
		// momsSavings = 200000;  // 如果妈妈有足够的储蓄就可以买到礼物
		priceOfPhone = 60000;
		if (momsSavings > priceOfPhone) {
			resolve({
				brand: "iphone",
				model: "6s"
			});
		} else {
			reject("我们没有足够的储蓄,让我们多存点钱吧。");
		}
	});
	momsPromise.then(function(value) {
		console.log("哇,我得到这个电话作为礼物 ", JSON.stringify(value));
	});
	momsPromise.catch(function(reason) {
		console.log("妈妈不能给我买电话,因为 ", reason);
	});
	momsPromise.finally(function() {
		console.log(
			"不管妈妈能不能给我买个电话,我仍然爱她"
		);
	});
Promise.prototype.then(onFulfilled, onRejected) 链式操作
- Promise.prototype.then()方法返回的是一个新的- Promise对象,因此可以采用链式写法
- Promise.prototype.then()方法带有以下三个参数:成功回调,失败回调,前进回调,一般情况下只需要实现第一个,后面是可选的
	function ptFir() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法1执行');
				resolve('方法1执行完毕');
			}, 2000)
		})
	}
	function ptSec() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法2执行');
				resolve('方法2执行完毕');
			}, 1000)
		})
	}
	function ptThi() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法3执行');
				resolve('方法3执行完毕');
			}, 3000)
		})
	}
	ptFir().then(function(data) {
		console.log('第一个回调:' + data);
		return ptSec();
	}).then(function(data) {
		console.log('第二个回调:' + data);
		return ptThi();
	}).then(function(data) {
		console.log('第三个回调:' + data);
		return '还没完?该结束了吧!';
	}).then(function(data) {
		console.log(data);
	})
Promise.prototype.catch(onRejected) 捕捉错误
- Promise.prototype.catch()方法是- Promise.prototype.then(null, rejection)的别名,用于指定发生错误时的回调函数
- Promise对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止,也就是说,错误总是会被下一个- catch语句捕获
	promise().then(function(data) {
		// todo something
	}).catch(function(err) {
		// 处理上个回调函数的错误
	})
Promise.prototype.finally(onFinally) 最终操作
不管promise对象最后的状态,在执行完.then或catch指定的回调函数以后,都会执行finally方法指定的回调函数
	promise().then(function(data) {
		// todo something
	}).catch(function(err) {
		// 处理上个回调函数的错误
	}).finally(function(result) {
		// 处理then/catch之后必须执行的操作
	})
Promise.resolve() / Promise.reject()
- 这两个是帮助方法或快捷方式,它们可以帮助您轻松创建resolve和reject方法
- 需要注意的是:如果Promise.resolve()方法的参数,
 不是具有.then()方法的对象(又称thenable对象),则返回一个新的Promise对象,且它的状态为fulfilled;
 如果Promise.resolve方法的参数是一个Promise对象的实例,则会被原封不动地返回
- Promise.reject()方法同上
	var promise = Promise.resolve('Hello,这里是执行成功的内容!');
	// var promise = Promise.reject('出错了,这里是被发现的错误!');  // 成功和失败只会有一种状态哦
	promise.then(function(data) {
		console.log(data)
	});
	promise.catch(function(err) {
		console.log(err)
	});
Promise.all()
- 当你处理多个promise时,最好先创建一个promise数组,然后对这些promise集执行必要的操作
- Promise.all(iterable) 方法返回一个- Promise实例,此实例在- iterable参数内所有的- promise
- 都完成(resolved)或参数中不包含promise时回调完成(resolve)
- 如果参数中promise有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败promise的结果
- 注意!!!这里的异步操作是并行执行的,等到它们都执行完后才会进到then()里面,
 并且all()方法会把所有异步操作的结果放进一个数组中传给then()
- 下面的示例需要说明的内容
- 只有3个方法的状态都变成fulfilled,p的状态才会变成fulfilled,此时3个方法的返回值组成一个数组,传递给p的回调函数
- 只要3个方法之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
 
- 只有3个方法的状态都变成
	function ptFir() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法1执行');
				resolve('方法1执行完毕');
			}, 2000)
		})
	}
	function ptSec() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法2执行');
				resolve('方法2执行完毕');
			}, 1000)
		})
	}
	function ptThi() {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				console.log('方法3执行');
				resolve('方法3执行完毕');
			}, 3000)
		})
	}
	Promise.all([ptFir(), ptSec(), ptThi()]).then(function(data) {
		console.log(data);
		console.log({}.toString.call(data));
	})
Promise.race()
- Promise.race(iterable)方法返回一个- promise,一旦迭代器中的某个- promise解决或拒绝,返回的- promise就会解决或拒绝
- all()方法的效果实际上是「谁跑的慢,以谁为准执行回调」 ,
 那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是- race()方法,这个词本来就是赛跑的意思
- 这个race()方法有什么用呢?使用场景还是很多的,比如我们可以用race()给某个异步请求设置超时时间,
 并且在超时后执行相应的操作
	// ptFir(), ptSec(), ptThi() 同上
	Promise.all([ptFir(), ptSec(), ptThi()]).then(function(data) {
		console.log(data);
		console.log({}.toString.call(data));
	})
使用Promise的一些经验法则
- 进行异步操作或使用阻塞代码时,请使用Promise
- 为了代码的可读性,resolve()方法对待.then(),reject()方法对应.catch()
- 确保同时写入.catch()和.then()方法来实现所有的promise
- 如果在这两种情况下都需要做一些事情,请使用.finally()
- 我们只有一次改变每个promise (单一原则)
- 我们可以在一个promise中添加多个处理程序
- Promise对象中所有方法的返回类型,无论是静态方法还是原型方法,都是- Promise
- 在all()方法中,无论哪个promise首先未完成,promise的顺序都保持在值变量中
参考文档一  ———— 彻底理解Javascript 中的 Promise
参考文档二  ———— 通俗浅显的理解Promise中的then
参考文档三  ———— 理解 Javascript 中的 Promise
参考文档四  ———— JavaScript Promise 对象

我是 fx67ll.com,如果您发现本文有什么错误,欢迎在评论区讨论指正,感谢您的阅读!
如果您喜欢这篇文章,欢迎访问我的 本文github仓库地址,为我点一颗Star,Thanks~ 
转发请注明参考文章地址,非常感谢!!!
快速入门上手JavaScript中的Promise的更多相关文章
- webpack快速入门——处理HTML中的图片
		在webpack中是不喜欢你使用标签<img>来引入图片的,但是我们作前端的人特别热衷于这种写法, 国人也为此开发了一个:html-withimg-loader.他可以很好的处理我们在ht ... 
- javascript中的promise和deferred:实践(二)
		javascript中的promise和deferred:实践(二) 介绍: 在第一节呢,我花了大量的时间来介绍promises和deferreds的理论.现在呢,我们来看看jquery中的promi ... 
- JavaScript中的Promise【期约】[未完成]
		JavaScript中的Promise[期约] 期约主要有两大用途 首先是抽象地表示一个异步操作.期约的状态代表期约是否完成. 比如,假设期约要向服务器发送一个 HTTP 请求.请求返回 200~29 ... 
- Vue.js——60分钟快速入门  开发· webpack 中文文档
		转载于:http://www.cnblogs.com/keepfool/p/5619070.html http://www.css88.com/doc/webpack2/guides/get-star ... 
- 通过一道笔试题浅谈javascript中的promise对象
		因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ... 
- Javascript中的Promise
		Promise定义 Promise是CommonJs的规范之一,包含resolve,reject,done,fail,then等方法,能够帮助我们控制代码的流程,避免函数的多层嵌套.异步在web开发中 ... 
- R语言快速入门上手
		导言: 较早之前就听说R是一门便捷的数据分析工具,但由于课程设计的原因,一直没有空出足够时间来进行学习.最近自从决定本科毕业出来找工作之后,渐渐开始接触大数据行业的技术,现在觉得是时候把R拿下 ... 
- 掌握JavaScript中的Promise,实现异步编程
		事件循环 基本介绍 JavaScript是一门单线程的编程语言,所以没有真正意义上的并行特性. 为了协调事件处理.页面交互.脚本调用.UI渲染.网络请求等行为对主线程造成的影响,事件循环(event ... 
- 彻底理解Javascript 中的 Promise(-------------------------------***---------------------------------)
		ES6原生提供了 Promise 对象. 到底是何方妖怪呢?打出来看看: 所谓 Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个 ... 
随机推荐
- css如何简单设置文字溢出盒子显示省略号
			1.单行文本溢出显示省略号单行文本溢出显示省略号,必须满足三个条件:(1)先强制一行内显示文本white-space:nowrap;(默认 normal自动换行)(2)超出的部分隐藏overflow: ... 
- Golang通脉之面向对象
			面向对象的三大特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不同实现方式 Go并不是一个纯 ... 
- 【UE4 C++】 启动 / 关闭外部exe、开启虚拟键盘
			启动/关闭外部exe 引擎自带 FPlatformProcess::CreateProc() FPlatformProcess::TerminateProc() windows api ShellEx ... 
- [软工顶级理解组] Alpha阶段事后分析
			目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 质量提高 会议截图 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰 ... 
- FastAPI 学习之路(五十九)封装统一的json返回处理工具
			这之前的接口,我们返回的格式都是每个接口异常返回的数据格式都会不一样,我们处理起来没有那么方便,我们可以封装一个统一的json处理. 那么我们看下如何来实现呢 from fastapi import ... 
- C语言教你写个‘浪漫烟花‘---特别漂亮
			效果展示 动态图 总体框架 /***************************************** * 项目名称:浪漫烟花 * 项目描述:贴图 * 项目环境:vs2019 * 生成日期: ... 
- 零基础学习C语言入门必备知识
			今天跟大家一起从零学C语言: 1. C语言简介 1.1 C语言发展史 C语言是一种广泛使用的面向过程的计算机程序设计语言,既适合于系统程序设计,又适合于应用程序设计.C语言的发展历程大致如图1-1所示 ... 
- 深入理解xLua基于IL代码注入的热更新原理
			目前大部分手游都会采用热更新来解决应用商店审核周期长,无法满足快节奏迭代的问题.另外热更新能够有效降低版本升级所需的资源大小,节省玩家的时间和流量,这也使其成为移动游戏的主流更新方式之一. 热更新可以 ... 
- Go并发编程--Mutex/RWMutex
			目录 一.前言 二. Mutex 2.1 案例 三. 实现原理 3.1 锁的实现模式 3.2 Go Mutex 实现原理 3.2.1 加锁 3.2.2 解锁 四. 源码分析 4.1 Mutex基本结构 ... 
- PE头详细分析
			目录 PE头详细分析 0x00 前言 0x01 PE文件介绍 0x02 PE头详细分析 DOS头解析 NT头解析 标准PE头解析 可选PE头解析 可选PE头结构 基址 代码段地址 数据段地址 OEP程 ... 
