学会Promise,看这里!!!
前言
众所周知,在JavaScript的世界中,代码都是单线程执行的。由于这个原因,JavaScript中的耗时操作,如网络操作、浏览器事件等,都需要异步执行。这也导致在JavaScript中异步操作是非常频繁且常见的。
异步:在执行某些耗时、不会立即返回结果的操作时,不会阻塞后面的操作,一旦该耗时操作完成时,立即通知需要调用其结果的函数来做后续处理。
而这种通知需要调用其结果的函数来做后续处理,一般都是通过回调的方式实现的。但是为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,就会出现”回调地狱“。比如说你要把一个函数 A作为回调函数,但是该函数又接受一个函数B作为参数,甚至B还接受C作为参数使用,就这样层层嵌套,人称之为回调地狱,代码阅读性非常差。比如:
var sayhello = function (name, callback) {
setTimeout(function () {
console.log(name);
callback();
}, 1000);
}
sayhello("first", function () {
sayhello("second", function () {
sayhello("third", function () {
console.log("end");
});
});
});
//输出: first second third end
而Promise作为一种可以优雅的解决这种”回调地狱“问题的方案,在实际开发中大面积使用,具有非常不错的效果。平时开发中,自己也经常看到这种情况,但是每次都是按照模板套路去编写业务代码,至于Promise是怎么使用的,根本没有学习总结过,导致自己总是一头雾水。这次,就认真的总结一下,同样的,只看样式,不究原理。待日后武义精益了,再来深挖掘。
Promise简介
Promise是异步编程的一种解决方案,是一个对象,可以获取异步操作的消息,大大改善了异步编程的困难,避免了回调地狱,比传统的解决方案回调函数和事件更合理和更强大。
从语法上讲,Promise是一个对象,它可以获取异步操作的消息。提供了一个统一的API,各种异步操作都可以用同样的方法进行处理。
首先了解下Promise的几个要点知识:
- 语法上,promise是一个构造函数;功能上,promise对象用来封装一个异步操作并获取执行的结果;
- 它有三种状态,pending(打包中,创建promise对象后的状态)、resolved(成功)、rejected(失败);
- 一个promise对象只能改变一次状态,成功或者失败后都会返回结果数据;
- 成功的结果数据一般称为value,失败的结果数据为reason。
Promise的实例有两个过程:
- pending > fulfilled :Resolved
- pending > rejected :Rejected
Promise基本用法
创建Promise对象
Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve
和reject
。
Promise创建时,会传给promise一个称为excutor执行器的函数。这个excutor我们可以理解为生产者的生产过程函数。这个函数含有两个参数resolve和reject,这俩参数也同样是函数,用来传递异步操作的结果。
let promise = new Promise(function(resolve, reject) {
// executor
})
重点说明:
- 在Promise对象创建时,excutor会立即执行;
- 在resolve和reject是JS引擎自动创建的函数,我们无需自己创建,只需将其作为参数传入就好。
then()
用法
Promise 实例生成以后,可以用 then 为实例添加状态改变时的回调函数。then
方法可以接收两个回调函数作为参数,第一个回调函数是Promise对象的状态改变为resoved
的调用,第二个回调函数是Promise
对象的状态变为rejected
的调用。其中第二个参数可以省略。
function getData() {
return new Promise(function(resolve, reject) {
var obj = {num : 0};
setTimeout(function(){ // 模拟异步请求
obj.num = Math.random();
resolve(obj);
}, 1000);
});
}
getData().then(function(obj){
console.log(obj.num);
});
getData函数返回一个promise实例,使用then
为它指定一个Resolved状态的回调函数,异步请求中传给resolve的值,将作为回调函数中的参数。当异步请求成功之后,回调函数变会执行输出对应的值。
假设异步请求失败了怎么办? then
其实还可以指定第二个可选的参数,即Rejected状态的回调函数。
getData().then(function(obj){
console.log(obj.num);
}, function(error){
console.log(error);
});
catch()
用法
在上述例子中,异步请求成功后,第一个回调函数会执行,如果失败了,第二个回调函数便会执行。
其实我们还可以使用catch
指定错误时的回调,catch
调用其实等同于使用then(undefined, function)
。上述代码和以下代码是同样的效果。
getData().then(function(obj){
console.log(obj.num);
}).catch(e){
console.log(e);
}
all()
用法
all
方法可以完成并进行任务,它接收的是一个数组,数组的每一项都是Promise对象。当数组中所有的Promise状态都达到resolved的时候,all
方法的状态就会变成resolved,如果有一个状态变成了rejected。那么all
方法的状态就会变成rejected。
let promise1 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(1);
}, 1000);
});
let promise2 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(2);
}, 2000);
});
let promise3 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(3);
}, 3000);
});
Promise.all([promise1, promise2, promise3]).then(function(res) {
console.log(res); // 输出 [1, 2, 3]
});
race()
用法
race
方法和all
一样,接收的参数是一个每项都是Promise的数组,但是与all
不同的是,当最先执行完的事件执行完之后,就直接返回该promise对象的值。
race
的实际作用:当要做一件事,超过长时间就不做了,可以用这个方法来解决。
let promise1 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(1);
}, 1000);
});
let promise2 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(2);
}, 2000);
});
let promise3 = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(3);
}, 3000);
});
Promise.race([promise1, promise2, promise3]).then(function(res) {
console.log(res); // 输出 1
});
finally()
用法
finally
方法用于指定不管Promise对象最后状态如何,都会执行的操作。finally
方法的回调函数不接受任何参数,这意味着没有办法知道前面的Promise状态到底是fulfilled还是rejected。
总结
由于自己对这个知识点掌握的少,所以这篇文章总结的很基础,希望对入门的选手有一个帮助。
学会Promise,看这里!!!的更多相关文章
- 跟着alex学习了格式化输出,最大的感受就是编程这个事,一定要自己动手去做,才能学会。看会和自己会做完全是两码事
学习了三天,现在学到格式化输出.看视频教程,alex和那个美女学员打情骂俏,真是羡慕啊. 教程看懂很容易,完全会了. 可是上手编程马上歇菜. 就这么几行的代码,我遇到了n多错误 首先是中文输入的错误, ...
- 手写Promise看着一篇就足够了
目录 概要 博客思路 API的特性与手写源码 构造函数 then catch Promise.resolved Promise.rejected Promise.all Promise.race 概要 ...
- js promise看这篇就够了
一.背景 大家都知道nodejs很快,为什么会这么快呢,原因就是node采用异步回调的方式来处理需要等待的事件,使得代码会继续往下执行不用在某个地方等待着.但是也有一个不好的地方,当我们有很多回调的时 ...
- ES6之Promise对象学习——8个例子学会Promise
目录 Promise 立即执行 Promise 三种状态 Promise 不可逆性 链式调用 Promise.then()回调异步性 Promise中的异常 Promise.resolve() res ...
- JavaScript异步编程——Async/Await vs Promise
兼容性 提醒一下各位,Node 现在从版本 7.6 开始就支持 async/await 了.而就在前几天,Node 8已经正式发布了,你可以放心地使用它. 如果你还没有试过它,这里有一堆带有示例的理由 ...
- STM32环境搭建/学习观点/自学方法 入门必看
文章转自armfly开发板V4软件开发手册,分享学习~ 今天有幸看到armfly的开发板软件开发手册,开头的基础知识,真的很有用,还好有看到,一切都不迟,感悟很多,摘抄部分,学习分享~ 关于开发环境的 ...
- 异步解决方案promise及源码实现
js语言的特性,造就了特别的异步处理方式,我记得以前用的最多的就是回调函数,那个时候写jquery的ajax时候,特别喜欢写这种代码: $.ajax({ method:'get', url:" ...
- Promise原理详解
参考文章:深入理解 Promise.[翻译]Promises/A+规范 从入门Promise的正确姿势中我们已经了解到Promise的基本用法.那么现在给你一个需求:根据Promise的用法和Prom ...
- Promise简单实现--摘抄
Promise 看了些promise的介绍,还是感觉不够深入,这个在解决异步问题上是一个很好的解决方案,所以详细看一下,顺便按照自己的思路实现一个简单的Promise. Promise/A+规范: 首 ...
- 渣渣菜鸡为什么要看 ElasticSearch 源码?
前提 人工智能.大数据快速发展的今天,对于 TB 甚至 PB 级大数据的快速检索已然成为刚需,大型企业早已淹没在系统生成的浩瀚数据流当中.大数据技术业已集中在如何存储和处理这些海量的数据上.Elast ...
随机推荐
- HBase Shell将命令执行结果导出到文件
1.将Hbase shell执行结果输出到文件 echo "scan 'test'" | hbase shell>my.txt 2.查看表的region数 list_regi ...
- 好书推荐之《Java 核心技术:卷 1 基础知识》
大佬推荐 <Java 核心技术:卷 1 基础知识>,这本书本来是 Sun 公司的官方用书,是一本 Java 的入门参考书. 对于 Java 初学者来说,是一本非常不错的值得时常翻阅的技术手 ...
- C++ 多线程的错误和如何避免(3)
传递给 C++ 线程的构造函数的参数是通过值传递的 VS 平台:2019 问题:如何在线程中改变传递的参数值? 比如: #include <functional> #include < ...
- django学习第八天--多表操作删除和修改,子查询连表查询,双下划线跨表查询,聚合查询,分组查询,F查询,Q查询
orm多条操作 删除和修改 修改 在一对一和一对多关系时,和单表操作是一样的 一对一 一个作者对应一个信息 ad_obj = models.AuthorDetail.objects.get(id=1) ...
- 使用俩个链接在一起的容器运行wordpress
# 问题,如何分离mysql和wordpress,使它们每个都单独运行一个容器. # 解决办法:运行时通过--link选项使它们链接在一起 --link <container_name>: ...
- SpringCloud使用Kafka消费者
目录 POM文件配置 创建kafka配置 系统配置信息 启动入口 POM文件配置 <project xmlns="http://maven.apache.org/POM/4.0.0&q ...
- 【Azure 事件中心】Event Hubs如何获取其中存放的历史消息
问题描述 使用Azure Event Hub服务,除了正常的生产,消费消息以外,如果想拿到Event Hub中存储的历史消息?有什么方法呢? 问题解答 获取 Event Hubs 存储的历史消息,首先 ...
- 【Azure 环境】各种语言版本或命令,发送HTTP/HTTPS的请求合集
问题描述 写代码的过程中,时常遇见要通过代码请求其他HTTP,HTTPS的情况,以下是收集各种语言的请求发送,需要使用的代码或命令 一:PowerShell Invoke-WebRequest htt ...
- 智联招聘基于 Nebula Graph 的推荐实践分享
本文首发于 Nebula Graph Community 公众号 本文整理自智联招聘资深工程师李世明在「智联招聘推荐场景应用」的实践分享 搜索推荐架构 在讲具体的应用场景之前,我们先看下智联招聘搜索和 ...
- dart特殊符号语法(一)
许久没有写博客.浏览以往的博客,是那么稚嫩.就让它们当成成长的照片吧.重新开始操起这个记录的爱好,一方面把它当成可以查阅的资料,方便自己:另一方面希望有帮助于人.由于个人能力,认知有限,如读者发现有纰 ...