Promise 学习笔记 - 时间支配者
本文同步自我的个人博客:http://www.52cik.com/2015/11/08/promise.html
JavaScript 的 promises 事实标准称为 Promises/A+。ES6 的 Promise API 便遵循这个标准。
promises 的英文直译是“承诺,诺言”。但是在张鑫旭大神的《ES6 JavaScript Promise的感性认知》文章里得知,
而是应该根据其音译——“普罗米修斯”,来翻译。普罗米修斯是希腊神话故事中的英雄,名字的意思是“先知”。
回调地狱
好了,我就不讲那些学术化的东西了,直接进入正题,来个实际的例子比什么都强。
例如我们有3个 ajax 请求,需要按照顺序加载。
$.get("/url1", function (data) {
// 一些处理
$.get("/url2", function (data) {
// 一些处理
$.get("/url3", function (data) {
// 最终处理
});
});
});
非常熟悉的画面,那如果请求增加到10个,甚至更多,会发生什么呢?

这幅图非常直观形象的展示了回调地狱。
时间支配 - 按顺序调度
为了避免回调地狱的发生,就需要 Promise 出马来合理的支配我们的任务时间。
首先需要学习下第一个 api,具体参阅 MDN Promise 文档。
其实非常简单,就是用 Promise 包装下 ajax 请求即可,代码如下。
// 用 Promise 包装 get 请求
function myGet(url) {
return new Promise(function(resolve, reject) {
$.get(url, resolve);
});
}
myGet('/url1').then(function (data) {
// 一些处理,data为返回值
return myGet('/url2');
}).then(function (data) {
// 一些处理
return myGet('/url3');
}).then(function (data) {
// 最终处理
});
这样就可以按顺序写 ajax 调用了,不会陷入无尽的回调之中。
如果你熟悉 jquery,那么你一定知道 Deferred,它实现了类似 Promise 的东西。
$.get("/url1").then(function (data) {
// 一些处理,data为返回值
return $.get("/url2");
}).then(function (data) {
// 一些处理
return $.get("/url3");
}).then(function (data) {
// 最终处理
});
这样看着简洁多了,虽然 Deferred 和 Promise 实现方法不一样,但是他们的结果是一致的。
时间支配 - 异步并发
大家都知道 ajax 异步请求是没有返回顺序的,发了3个请求,有可能是1,2,3的返回,也有可能是3,1,2的返回顺序。
那我不想按顺序请求,而是并发请求,但是在最终所有请求完成后执行一段操作。
比如页面所有数据都加载完后隐藏 loading 层。
这个时候,需要用到一个新方法 Promise.all,其实很简单,它接受一个 promise 数组最为参数。
function myGet(url) {
return new Promise(function(resolve, reject) {
$.get(url, resolve);
});
}
var arr = [];
arr.push(myGet('/url1'));
arr.push(myGet('/url2'));
arr.push(myGet('/url3'));
Promise.all(arr).then(function (datas) {
// 最终处理,datas 是所有返回结果的数组
console.log("返回数据为", datas);
});
感觉比刚才的按顺序还要清爽,有木有。其实 jquery 也有类似的功能,而且用起来超爽的。
$.when($.get('/url1'), $.get('/url2'), $.get('/url3'))
.then(function (data1, data2, data3) {
// 最终处理
console.log("返回数据为", data1, data2, data3);
});
虽然形式有点怪异,不过调整下就OK了。
var arr = [];
arr.push($.get('/url1'));
arr.push($.get('/url2'));
arr.push($.get('/url3'));
$.when.apply(null, arr).then(function () {
// 最终处理
console.log("返回数据为", arguments);
});
利用 apply 来展开参数,代码看着舒服多了,跟上面的 Promise.all 是一样一样的。
结束语
本文本是我在一边学习测试一边写的,例子都跑过OK的,通篇下来后,对 Deferred 和 Promise 有了一定认识,
虽然并不一定透彻,至少比起以前好多了。
为什么叫它为 时间支配者 呢,一开始没这样的想法,写到一半的时候发现确实可以合理的支配异步的时间调度问题。
异步操作最大的特点就是时间的不确定性,所以正常情况下很难流畅的书写简单而有逻辑性的代码。
比如按顺序的异步,虽然可以合理的回调,但是会陷入回调地狱,再如并发异步呢?
并发异步,也许你要设置一个全局变量来记次,最后一个完成的,要触发下完成后的任务。
这样虽然也可以实现,但是代码会显的臃肿而又凌乱。
但是有了 Promise 的帮助,这一切变的这么简单,自然。
Promise 学习笔记 - 时间支配者的更多相关文章
- Javascript - Promise学习笔记
最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下. 一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...
- JavaScript之Promise学习笔记
一直想知道Promise到底是怎么实现的,网上一搜几十篇文章,看的一脸蒙蔽.最后算是找到几个讲的真心很详细明了的.看了一份源码看了很久很久……最后找大佬问了几处看不懂的地方,大佬只看了十几分钟就看懂了 ...
- js的Promise学习笔记(1)
1: 何为Promise Promise是抽象异步处理对象以及对其对象进行各种操作的组件,是基于并列/并行处理设计的一种编程语言. 说到基于JavaScript的异步处理,大多数都会想到利用回调函数. ...
- Promise 学习笔记
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息.Promise提供统一的API, ...
- Javascript Promise 学习笔记
1. 定义:Promise是抽象异步处理对象以及对其进行各种操作的组件,它把异步处理对象和异步处理规则采用统一的接口进行规范化. 2. ES6 Promises 标准中定义的API: ...
- Promise学习笔记
Promise对象 Promise 表示一个异步操作的最终结果,与之进行交互的方式主要是 then 方法,该方法注册了两个回调函数,用于接收 promise 的终值或本 promise 不能执行的原因 ...
- ES6 promise学习笔记 -- 基本用法
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. 下面代码创造了一个Promise实例. const promise = new Promise(function(reso ...
- JavaScript:学习笔记(9)——Promise对象
JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...
- WeX5学习笔记
目录 WeX5学习笔记... 1 1.轻松看透WeX5产品能力和技术... 1 2.WeX5可以怎么玩?... 3 一.纯本地App. 3 二.关联一个网站,希望默认就打开某页... 4 三.UI设计 ...
随机推荐
- 编译时:virtual memory exhausted: Cannot allocate memory
一.问题 当安装虚拟机时系统时没有设置swap大小或设置内存太小,编译程序会出现virtual memory exhausted: Cannot allocate memory的问题,可以用swap扩 ...
- CS193P学习笔记(一)
1>iOS系统分层 1.Core OS 核心操作系统层,很接近硬件的一层: 本质是一个Unix内核,使用基于BSD的Unix版本,拥有文件系统.套接字.权限等一系列Unix所具有的特性,并且 ...
- EXCEL IF 函数 模糊查询
A列都是产品名,比如衬衫,长袖衬衫,短袖衬衫,短裙,长裙 搜索A列的产品名,凡是含有“衬衫”的一律在B列对应行输出“衬衫”,凡是含有“裙”字的一律输出“裙子”在B列对应行,请教一下怎么写函数,本来用I ...
- C自学笔记-递归与迭代的使用方法笔记与两者的使用场合
递归和迭代在刚开始学C语言的时候就学过,但是不知道怎么使用.今天遇到一个题目分析过后 我瞬间想起来之前学过递归的方法,做完题后顺便翻了翻书整理了这个笔记.题目大概是这样的. 题目:猴子吃桃问题:猴子第 ...
- 杂谈SharpDx中的WIC组件——我们需要WIC的图片编码功能么?
在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作.可能是我的设置问题,也可能是Sha ...
- MIT jos 6.828 Fall 2014 训练记录(lab 1)
注: 源代码参见我的github:https://github.com/YaoZengzeng/jos Part 1: PC Bootstrap +------------------+ <- ...
- ZBrush中必须记住的常用快捷键
ZBrush是一款数字雕刻和绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维雕刻行业.强大的功能离不开便捷的操作,为此ZBrush提供了一系列常用操作快捷键,熟练掌握这些快捷键,可帮助您节省 ...
- 解决WordPress后台安装主题、插件图片不显示的问题
今天搭建wordpress发现现在主题的时候预览图片都没有了,于是搜索了一下,发现下面的这个方法确实管用,于是转载收藏. 有在WordPress后台安装主题.插件的小伙伴可能会遇到主题.插件图片不显示 ...
- Lambda 表达式(C# 编程指南)
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数.Lambda 表达式对于编写 LINQ 查 ...
- laravel记录
1.使用数据库事务的时候需要传递参数,使用了use关键字,否则的话传递不进去,代码如下: public function postVote(Request $request){ $data = $re ...