概述

就像谈到闭包必须要说js变量作用域一样,谈到 promise 之前肯定要先说谈异步编程。一直以来, javascript 处理异步方式都是使用 callback 方式,对与写 javascript 的人来时候 callback 深入人心。比如只有前端经验没有后端经验的同学看到 java 代码可能会问『为什么readFile方法可以直接返回结果?为何不使用 callback 』

由于 javascript 的单线程性质,必须等待上一个事件执行完成才能处理下一步。传统解决 javascript 异步编程的方法就是使用 callback,比如这样:

$(document).ready(function(){
ajaxGet('/api/userinfo', function() {
ajaxGet('/api/productList', function() {
ajaxGet('/api/ads', function(result) {
console.log('all done!');
});
});
});
});

再比如这样:

截止到2015年10月20日晚,http://www.kuaidadi.com/assets/js/animate.js还可以访问。

『快的』用线上代码为我们生动的演示了什么叫callback hell——『回调地狱』。

promise

Promise 字面上可以理解为『承诺』,即A调用B,B返回一个『承诺』给A,然后A就可以认为B给我返回结果的时候我就执行方案一了,反之没有得到结果就执行方案二。

上面这句话翻译为代码:

var resB = B();
var runA = function() {
resB.then(execPlan1, execPlan2);
}
runA();

Promise 是一种异步操作模式,表示一个异步操作的最终结果,返回的是一个 Promise 对象,由于是立即返回,所以可以采用同步操作的流程。 这个 Promise 对象有一个 then 方法,允许指定回调函数,在异步任务完成后调用。

比如上面『快的』的例子可以改写为这样:

(new Promise(step1))
.then(step2)
.then(step3)
.then(step4)
.then(step5)
.then(step6)
.then(step7)
.then(step8)
.then(step9)
.then(step10)
.then(step11)
.then(step12)
.then(step13)
.then(step14)
.then(step15)
.then(step16)
.then(step17);

看,『横向的胖子』变的苗条了,看起来是不是更加可爱呢?

Promise有个一个规范叫做 Promises/A+, 有各种各样的第三方库遵循这个规范实现了 Promise/A+ 。 比如 Q、 when, jQuery 有个类似的方法叫 Deferred。

一个 Promise 对象的实例一般有三种状态:未完成(pending)、已完成(fulfilled)和失败(rejected)。

这三种的状态的变化途径只有两个,且只能发生一次:从“未完成”到“已完成”,或者从“未完成”到“失败”。

一旦当前状态变为“已完成”或“失败”,就意味着不会再发生状态变化了。

Promise对象的运行结果,最终只有两种。

得到一个值,状态变为fulfilled

抛出一个错误,状态变为rejected

参考阅读

JavaScript Promise启示录

JavaScript Promise迷你书(中文版)

JavaScript Promises

javascript.ruanyifeng.com

Promise/A+规范

本文首发于 http://fy98.com/2015/10/20/from-callback-hell-to-promise/

从快的线上callback hell代码说起的更多相关文章

  1. 如何使用Fiddler调试线上JS代码

    大家平时肯定都用过火狐的Firebug或者谷歌的调试工具来调试JS,但遗憾的是我们不能像编辑html,css那样来直接新增或者删除JS代码. 虽然可以通过调试工具的控制台来动态执行JS代码,但有时候却 ...

  2. webpack线上和线下模式

    区别: 1 线下模式代码没有压缩,source-map是全的,比较容易定位错误,调试方便 2 线上模式的代码是压缩的,文件小, 分开打包: 方式一:有点麻烦 在package.json文件 " ...

  3. 前端通信:SSE设计方案(二)--- 服务器推送技术的实践以及一些应用场景的demo(包括在线及时聊天系统以及线上缓存更新,代码热修复案例)

    距离上一篇博客,这篇文章的发布大概过了整整三个月.我也从饿了么度过了试用期,成为了正式员工.刚进来恰好遇到项目底层改造和迁移,将项目从angular全部迁移到vue上,所以适应这边的节奏和业务的开发任 ...

  4. 如何用 fiddler 调试线上代码

    有时代码上线了,突然就碰到了坑爹的错误.或者有时看别人家线上的代码,对于一个文件想 fork 下来试试效果又不想把全部文件拉到本地,都可以使用 fiddler 的线上调试功能. 比方说我们打开携程的首 ...

  5. 如何利用Grunt生成对应的Source Map文件,线上代码压缩使用chrome浏览器便于调式

    如何利用Grunt生成对应的Source Map文件,线上代码压缩使用chrome浏览器便于调式 首先我们来说说为何要生成sourceMap文件呢?简单的说,sourceMap是为了压缩后的代码调式提 ...

  6. 分享下使用 svn,测试服务器代码自动更新、线上服务器代码手动更新的配置经验

    分享下使用 svn,测试服务器代码自动更新.线上服务器代码手动更新的配置经验 利用SVN的POST-COMMIT钩子自动部署代码 Linux SVN 命令详解 Linux SVN 命令详解2 使用sv ...

  7. Springboot拦截器线上代码失效

    今天想测试下线上代码,能否正常的执行未登录的拦截.所以把拦截器的代码给开放出来,但是没想到线上代码addInerceptors(InterceptorRegistry registry) 这个方法一直 ...

  8. 用PhpStrom线上连接修改linux服务器上代码配置

    为了进一步提高自己的技能水平,不久前入手了一台服务器,不贵,一年也就不到两百,因为自己对于linux机器比较生疏,命令用的有点抠脚.老需要查阅处理. 于是我选择用PhpStrom直接连接线上服务器,通 ...

  9. 不停机替换线上代码? 你没听错,Arthas它能做到

    写在前边 有没有这样一种感受,自己写的代码在开发.测试环境跑的稳得一笔,可一到线上就抽风,不是缺这个就是少那个反正就是一顿报错,线上调试代码又很麻烦,让人头疼得很.阿里巴巴出了一款名叫Arthas的工 ...

随机推荐

  1. APP测试工具之TraceView卡顿检测

    Traceview卡顿检测 Traceview是Android平台特有的数据采集和分析工具,集成在DDMS工具中,可以采集程序中的方法执行耗时.调用关系.调用次数以及资源占用等情况. 一.使用方法 1 ...

  2. 项目支持Servlet3.0的新特性

    一.Servlet3.0介绍 Servlet3.0是Java EE6规范的一部分,Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述 ...

  3. jquery ajax load

    jQuery load() 方法 jQuery load() 方法是简单但强大的 AJAX 方法. load() 方法从服务器加载数据,并把返回的数据放入被选元素中. 语法: $(selector). ...

  4. LoadRunner ---思考时间设置

    用户访问某个网站或软件,一般不会不停地做个各种操作,例如一次查询,用户需要时间查看查询的结果是否是自己想要的.例如一次订单提交,用户需要时间核对自己填写的信息是否正确等. 也就是说用户在做某些操作时, ...

  5. Mysql错误信息汇总

    目录: 1. Every derived table must have its own alias 内容: 1. Every derived table must have its own alia ...

  6. Spring----->projects----->Spring Boot

    1.概述:(about Spring Boot) Spring boot是在spring framework的基础上搭建起来的一个基本项目,该项目中已经集成了spring框架下的若干模块以及sprin ...

  7. crontab这个坑,执行单个命令执行成功,但是写到crontab怎么也不行

    昨天开始,一直在弄通过定时任务控制熄屏,在终端下的单个命令可以执行成功,写到脚本里,单个执行脚本能成功,但是写到crontab定时任务,怎么也不熄屏,但他确实执行了,看日志,是一直报错的:百度了很多很 ...

  8. iOS /* */多个嵌套解决

    解决办法 #if 0 /* */ #endif

  9. Python_sklearn机器学习库学习笔记(三)logistic regression(逻辑回归)

    # 逻辑回归 ## 逻辑回归处理二元分类 %matplotlib inline import matplotlib.pyplot as plt #显示中文 from matplotlib.font_m ...

  10. mysql 命令行参数

    MySQL命令行参数 Usage: mysql [OPTIONS] [database] //命令方式  例如: mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAM ...