今天来学习下Promise吧,其实这在笔试上也是一个考点.

基本介绍

Promise对象是CommonJS(熟悉的名字吧- -)工作组提出的规范.Promise原本只是社区提出的构想,一些外部函数库率先实现了该功能,ES6中将其写入了语言标准.
目的:为异步操作提供统一接口

Promise是啥,它就是一个javascript中一个对象,起着代理作用,充当异步操作与回调函数之间的中介.
避免类似于

这种嵌套地狱的产生.让我们的代码变得更加简单易读
使用了Promise,大家都说好

(new Promise(f1).then(f2));

总结:Promise使得异步操作的向下发展变成横向发展,程序流程变得清晰,易于阅读.

基本思想

  • 异步任务返回一个Promise对象,它有三种状态

    • pending(未完成)

    • resolved,fulfilled(已完成)

    • rejected(失败)

  • 它有两种变化途径

    • pending --> resolved/fulfilled

    • pending --> rejected

  • 它有两种结果

    • 异步操作成功,返回一个值,状态变为resolved

    • 异步操作失败,抛出一个错误,状态变为rejected

Promise使用.then()方法添加回调函数,then接收两个回调函数,第一个为成功时的回调函数,另一个为失败时的回调函数.主要为状态改变时调用相对的回调函数.
而且then可以链式调用.

基本使用

Promise构造函数接受一个函数作为参数,而该函数两个参数分别是resolvereject.它们由JS引擎提供,不需要自己部署.

Promise(function(resolve,reject){})

resolve函数作用为:将Promise对象从未完成变为成功(Pending->Resolved),异步操作成功时调用,并将异步操作的结果作为参数传递出去.
reject函数作用为:将Promise对象从未完成变为失败(Pending->Rejected),异步操作失败时调用,并将异步操作报出的错误作为参数传递出去.


Promise.then()方法可以用于指定Resolved状态和Reject状态的回调函数.

promise.then(function(value){//成功+_+!},function(value){//失败Q_Q});

我们只想对异常进行处理时可以采用promise.then(undefined, onRejected)这种方式,或者promise.catch(onRejected)
!注意!此处有坑,接下来在深入节会进行讲解


Promise.all()方法接收一个promise对象的数组为参数,当这个数组中所有的Promise对象全部变成resolve/reject状态的时候,才会调用.then方法,其中传入的promise是同时开始,并行执行的.

promise.all([promise1,promise2,.....]);

Promise.race()方法和Promise.all()方法一样接收一个promise对象的数组作为参数,但是数组中有一个promise对象进入fulfilled或rejected状态,就会开始后续处理.

promise.race([promise1,promise2,.....]);

相关的语法糖

Promise.resolve(42);
//等价于
new Promise(function(resolve){resolve(42);
});Promise.reject(new Error("出错了"));
//等价于
new Promise(function(resolve,reject){reject(new Error("出错了"));
});

深入

关于Thenable对象

这是非常类似于Promise的东西,拥有.then方法.
其中比较经典的例子就是jQuery.ajax()返回的值就是thenable的.

var promise = Promise.resolve($.ajax('/json/comment.json'));

这样就可以将thenable对象转化为promise对象
传送门:Promise.resolve()

关于promise设计:总是异步操作

看代码就能明白这个地方的问题了.

var promise = new Promise(function (resolve){console.log("inner promise"); // 1resolve(42);
});
promise.then(function(value){console.log(value); // 3
});
console.log("outer promise"); // 2
//结果是
/*
inner promise // 1
outer promise // 2
42            // 3
*/

可以看出,即使我们调用promise.then时promise对象已经确定状态,Promise也会以异步的方式调用回调函数,这就是Promise设计上的规定方针.

关于调用then/catch

每次调用then/catch,都会返回一个promise对象,这一点上我们通过使用===就可以判断出来每次promise对象其实都是不一样的

then和catch的错误处理区别

这点和上一点联合起来很容易理解
直接上图吧,来自于JavaScript Promise迷你书(中文版)

在结合我们的代码吧

// <1> onRejected不会被调用
function badMain(onRejected) {return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有异常发生时onRejected会被调用
function goodMain(onRejected) {return Promise.resolve(42).then(throwError).catch(onRejected);
}

onFullfilled中发生的错误,如在<1>里面throwError中的错误,是不会导致onRejected的执行(捕获异常)的,我们只能通过后面的catch方法才能捕获.

基本应用

不兼容方面

  1. 不兼容就是用polyfill

  2. 关于IE8以及以下版本中,catch会由于在ES3中为保留字,导致identifier not found错误,对此我们可以通过["catch"]或者then(undefined,function(){})来进行catch,而某些类库中,采用了caught作为函数名来规避该问题.值得注意的是,有很多压缩工具中自带了.catch转["catch"]

应用示例:
加载图片

var preloadImage = function(path){return new Promise(function(resolve,reject){var image = new Image();image.onload = resolve;image.onerror = reject;image.src = path;})
}
preloadImage("https://dn-anything-about-doc.qbox.me/teacher/QianDuan.png").then(function(){alert("图片加载成功");
},function(){alert("图片加载失败");
})

Ajax操作

function search(term) {var url = 'http://example.com/search?q=' + term;var xhr = new XMLHttpRequest();var result;var p = new Promise(function(resolve, reject) {xhr.open('GET', url, true);xhr.onload = function(e) {if (this.status === 200) {result = JSON.parse(this.responseText);resolve(result);}};xhr.onerror = function(e) {reject(e);};xhr.send();});return p;
}
search("Hello World").then(console.log, console.error);

回到最初吧,其实Promise对象优点还是在于规范的链式调用,可以清晰看出程序流程.并且对于错误还能定义统一的处理方法.

Promise学习:基础入门相关推荐

  1. 文案层次感文字设计#ps教程#PS抠图学习基础入门

    文案层次感文字设计#ps教程#PS抠图学习基础入门

  2. AE学习基础入门小结

    AE 学习  基础知识总结: 1.全选图层  按p键调出位置信息. 2.CTRL+D 复制图层. 3.打关键帧  先调帧按钮  在改变属性.按空格播放. 4.打开图表编辑器 5.圆角矩形工具:拖出图形 ...

  3. Docker 学习 基础入门 B站狂神 个人私人笔记

    前置知识: linux基础命令.springboot知识 Docker 概述 docker 为什么出现 开发-运维 环境配置十分麻烦 每一个机器都要部署环境(集群Redis.ES.Hadoop...) ...

  4. 深度学习基础入门(一):基本概念和术语解读

    本文旨在解释一些深度学习中的基本概念,并通过一些实践中的例子帮助理解,可能个人解读有误,还望指正.本文提纲参照参考文献[2]进行,对其简练的内容加以了丰富和扩展,确保零基础的新手也可以有比较清晰的认识 ...

  5. html前端学习基础入门教程之HTML代码的优化 关键词密度

    与Google和MSN相比,Yahoo!对HTML代码的关注程度更高.很多测试表明,HTML文件中的错误,可能在Google或MSN中影响很小甚至几乎没有,不妨碍该页面出现在SERP的前端;但在Yah ...

  6. NLP学习基础入门(上)

    NLP (Natural Langunge Possns,自然语言处理)是计算机科学领域以及人工智能领域的一个重要的研究方向,它研究用计算机来处理.理解以及运用人类语言(如中文.英文等),达到人与计算 ...

  7. 深度学习基础入门篇[五]:交叉熵损失函数、MSE、CTC损失适用于字识别语音等序列问题、Balanced L1 Loss适用于目标检测

    [深度学习入门到进阶]必看系列,含激活函数.优化策略.损失函数.模型调优.归一化算法.卷积模型.序列模型.预训练模型.对抗神经网络等 专栏详细介绍:[深度学习入门到进阶]必看系列,含激活函数.优化策略 ...

  8. A.深度学习基础入门篇[四]:激活函数介绍:tanh、sigmoid、ReLU、PReLU、ELU、softplus、softmax、swish等

    [深度学习入门到进阶]必看系列,含激活函数.优化策略.损失函数.模型调优.归一化算法.卷积模型.序列模型.预训练模型.对抗神经网络等 专栏详细介绍:[深度学习入门到进阶]必看系列,含激活函数.优化策略 ...

  9. Linux 学习基础入门之Linux发展史

    [daodu] Linux发展史1. 什么是操作系统我们在使用电脑时候,一般是使用应用程序的,你比如说我现在在Chrome浏览器访问云栖社区.Chrome运行在操作系统上,操作系统驱动硬件,也就是我们 ...

最新文章

  1. 大公司病(太现实了!)
  2. jquery 使用jquery操作Dom
  3. java拉姆达表达式事例,Java Lambda表达式详解和实例
  4. socketmq 设置队列大小_C++编程实例:面向对象的整形队列实现
  5. python selenium 文件上传_python+selenium 文件上传
  6. 牛客 - 张老师的旅行(dp)
  7. 利用Underscore求数组的交集、并集和差集
  8. 深入理解 操作系统 LRU算法(以洛谷P1540题为例)
  9. spanner 的前世今生
  10. 信息学奥赛一本通(1069:乘方计算)
  11. 大家马致远是哪个朝代的,马致远作品赏析
  12. 显示低帧率排查思路记录
  13. xp系统设置锁定计算机,XP系统电脑如何设置自动锁屏?
  14. n9 android rom,美如画N9盒子线刷固件rom升级包下载(全志H8芯片)
  15. 如何做好客户需求分析
  16. SD卡无法格式化方法介绍
  17. 高等数学强化3:一元函数积分学 P积分
  18. linux装软件需要root用户,Linux下非root用户安装软件的一般流程:
  19. 程序员健康指南 真的很受用
  20. 搭建webdav文件共享服务器,使用Nginx搭建WebDav作为简易共享空间

热门文章

  1. python中模拟浏览器抓取网页(-)
  2. 【ansys workbench】3.圆角L型支架的应力结果
  3. 【目标定位】基于matlab粒子滤波的定位算法【含Matlab源码 2161期】
  4. 深度学习中number of training epochs中的,epoc h到底指什么?
  5. 你还在关注 AGV,而 AMR 已经悄然崛起
  6. H1B工作签证·绿卡:美国留学的两个关键步骤
  7. 微信开放平台开发第三方授权登陆(三):Android客户端
  8. PV UV IP的意义
  9. Linux 自定义service,并重定向输出到日志文件
  10. 老主板N卡点的亮A卡点不亮、只有VGA和DVI亮解决思路