Promise

Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

如果某些事件不断地反复发生,一般来说,使用stream模式是比部署Promise更好的选择。

为什么使用Promise

Simple demo

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>let user;//fetch all users$.get('https://api.github.com/users',data=>{console.log('fetched all users');user = data[0].login;});//fetch the first user's repos$.get(`https://api.github.com/users/${user}/repos`,data =>{console.log('fetched user repos');console.log(data);})
</script>

实现对github的用户信息的请求:

从图中看到,先进行了user的请求,然后是repos的请求。

第一次运行结果:

第二次运行结果:

同样的代码,同样的请求,却出现了不同的结果。

First -- 解决方法

将第二个请求写入在第一个请求的回调函数中(一直是这一种输出结果):

通过写入在回调函数中,可以确保其执行顺序不会出错。但是如果请求太多,这样多次嵌套,不仅代码不太美观,严重的会进入回调地狱中。

使用Promise

加入axios包:

返回值:

返回某一用户的repos:

创建自己的Promise

const p = new Promise((resolve, reject) => {resolve('it worked');
});p.then(data => {console.log(data);})

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

使用计算器模拟异步等待操作:

const p = new Promise((resolve, reject) => {setTimeout(() =>{resolve('it worked');})
});p.then(data => {console.log(data);})

2秒之后输出:it worked。对于错误信息的处理,同样是:

const p = new Promise((resolve, reject) => {setTimeout(() => {// resolve('it worked');reject('it is not worked');})
});p.then(data => {console.log(data);
}).catch(err => {console.log(err);
})

Promise Example

const repos = [{name: 'jack1',owner: 'Jackyjk1',description: 'Cool1',id: 1},{name: 'jack2',owner: 'Jackyjk2',description: 'Cool2',id: 2},{name: 'jack3',owner: 'Jackyjk3',description: 'Cool3',id: 3},
];const owners = [{name: 'Jackyjk1',location: 'Shaanxi Xian',other: false},{name: 'Jackyjk2',location: 'Shaanxi Baoji',other: false},{name: 'Jackyjk3',location: 'Shaanxi Xianyang',other: true},
]function getRepoById(id) {//创建Promise对象return new Promise((resolve, reject) => {//查找IDconst repo = repos.find(repo => repo.id === id);//处理方法if (repo) {resolve(repo);} else {reject(Error('NO repo found'));}})
}getRepoById(1).then(repo => {//返回找到的值// console.log(repo);return comboundOwner(repo);}).then(repo => {console.log(repo);}).catch(err => {console.log(err);})

//寻找相同的owner
function comboundOwner(repo) {return new Promise((resolve, reject) => {const owner = owners.find(owner => owner.name === repo.owner);if (owner) {resolve(owner);} else {reject(Error('Can not found the owner.'));}})
}getRepoById(1).then(repo => {//返回找到的值// console.log(repo);return comboundOwner(repo);}).then(repo => {console.log(repo);}).catch(err => {console.log(err);})

如果id传值为5,这个是不会找到的,就会触发错误机制:

多个Promise使用

Promise.all()方法

只有所有的方法返回值都是resolve时,才进行返回值,否则会触发catch方法。

Promise.all方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。

const usersPromise = new Promise((resolve, reject) => {setTimeout(() => {resolve(['jack1', 'jack2', 'jack3']);}, 3000);
});const moviePromise = new Promise((resolve, reject) => {setTimeout(() => {resolve({name: '战狼2',rating: 9.8,year: 2018});}, 1500);
});Promise.
all([usersPromise, moviePromise]).then(reponses => {console.log(reponses);}).catch(err => {console.log(err);})

Promise.race()方法

更改上面代码中的all为race,只要有usersPromise,moviePromise一个实例率先改变状态,Promise的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给Promise的回调函数。根据第一个结果的返回值直接返回结果

其他方法

Promise_相关方法

ES6学习 - Promise对象相关推荐

  1. 【ES6】Promise对象详解

    [ES6]Promise对象详解 一.Promise对象的含义 二.Promise对象的用法 三.Promise对象的几个应用[重点] 1.时间延迟函数 2.图片异步加载 查看更多ES6教学文章: 参 ...

  2. 谈谈 ES6 的 Promise 对象

    2019独角兽企业重金招聘Python工程师标准>>> 谈谈 ES6 的 Promise 对象 异步编程 promise es6 javascript 前言 开篇首先设想一个日常开发 ...

  3. 第十八节:教你如何使用ES6的Promise对象

    Promise对象,ES6新增的一个全新特性,今天我们要好好学习一下它. Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意儿,用它是为了解决什么问题? 带着这个问题,我们 ...

  4. [ES6] 细化ES6之 -- Promise对象

    Promise对象是什么 Promise对象是什么 ES6新增了Prormnise对象,该对象允许对延迟和异步操作流程进行控制.一个Promise对象就是一个代表了异步操作最终完成或者失败的对象. 开 ...

  5. 自学-ES6篇-Promise对象

    1.Promise Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise ...

  6. 使用ES6中Promise对象来封装ajax操作 以及then方法的返回值

    1 Promise的含义 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Pr ...

  7. es6 --- 用promise对象实现Ajax操作的一个实例

    首先回顾一下Ajax请求的步骤 var client = new XMLHttpRequest(); client.open("GET", url); client.onready ...

  8. 【ES6】阮一峰ES6学习(四) 对象的扩展

    对象的扩展 1. 属性的简洁表示法 ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法.这样的书写更加简洁. const foo = 'bar'; const baz = {foo}; ...

  9. 【ES6学习】对象的解构赋值

    解构不仅可以用于数组,还可以用于对象. let { foo , bar } = { foo :"aaa ", bar :"bbb " } ; too // &q ...

最新文章

  1. 软件测试工程师职业介绍和规划
  2. 负载均衡器技术 Nginx VS F5 Big-IP
  3. Python基础-----while循环语句
  4. Py之albumentations:albumentations库函数的简介、安装、使用方法之详细攻略
  5. 福大软工 · 第十二次作业 - Beta答辩总结
  6. 在ffmpeg中加入x264模块
  7. 如何获得物体的主要方向?
  8. django,cbv,模板层
  9. Scala学习(六)练习
  10. Spring @Service批注
  11. java jxl label_jxl.write.label
  12. Django中Python3安装Crypto使用RSA
  13. 史上最强三千六百道脑筋急转弯(4)
  14. 一、vmware的安装
  15. Sampler 半小时快速搭建PostgreSQL简易监控
  16. ubuntu root账户下添加和删除用户
  17. 如何让好习惯成为你人生中的一部分
  18. 【Mac 系列】Mac安装Mysql
  19. 云服务器安装数据库MySQL后,MySQL不能从外部连接的原因及解决
  20. 关于Linux下病毒的话题

热门文章

  1. ICCV 2019 | 旷视研究院提出文字检测新方法:像素聚合网络PAN
  2. 重磅快讯:CCF发布最新版推荐中文科技期刊目录
  3. java中如何传递参数给控制器_如何使用ui-router中的ui-sref将参数传递给控制器
  4. Python中用numpy进行图片处理
  5. 8 个Python技巧 每天工作效率高一点 升职快人一步
  6. 【OpenCV】OpenCV函数精讲之 -- argc 和argv参数
  7. ibm量子计算机科学家,量子计算机比传统计算机更具优势?IBM科学家这样说……...
  8. c花体复制_花式字体大全可复制 花式字体转换器
  9. 使用google map实现周边搜索的功能_「转」“搜索”的原理,架构,实现,实践,面试不用再怕了...
  10. linux内核的外部接口函数,linux内核中GPIO的使用(二)--标准接口函数