初识JavaScript Promises

JavaScript有很多槽点,嵌套回调怕是千夫所指。

很久之前,我一直使用async来处理JavaScript异步编程中的嵌套回调问题。当然我也大概的了解过一些其它旨在解决这些问题的类库,诸如EventProxy、Jscex、StepJS、thenjs。

当我第一次看到Promises规范的时候,我根本无法理解它所带来的好处。譬如每个初次学习Promises的人都见过如下的示例代码:

//callbacks
    function callback(err, value){
        if(err){
            // do something
            return;
        }
        //do other things     with value
    }
    //Promises
    promise.then(function(value){
        //do something with value
    }, function(err){
        //do other things with error
     })

很难相信上面的代码会让人对Promises刮目相看。不过正如bluebird作者Petka所说,上面的代码是
“最不诚实的比较”。所以我恳请你把类似的代码从你的记忆中擦出吧。

不妨让我们再回到async的讨论上。async的问题在于它不能优雅地应对需求的变化,一旦业务逻辑有较大的变化,代码结构会进行大幅度的调整,而Promises却能够轻松的应对这种变化。待时机适宜我会进行详细的比较,首先让我们开始快速地了解Promises。


Promises是什么

Promises象征着一个异步操作的最终结果。Promises交互主要通过它的then方法,then方法接受一个回调函数,这个回调函数接受执行成功的返回值或执行失败的错误原因,错误原因一般是Error对象。需要注意的是,then方法执行的返回值是一个Promise对象,而then方法接受的回调函数的返回值则可以是任意的JavaScript对象,包括Promises。基于这种机制,Promise对象的链式调用就起作用了。

Promises的状态

Promise对象有三种状态:pending(初始状态)、fulfilled(成功执行)、rejected(执行出错)。pending状态的Promise对象可以转换到其它两种状态。



上面的文本不够形象,不妨上些代码来加深对Promises的认识。

注:由于主流的JavaScript环境(包括NodeJS)对Promises/A+标准的实现不太令人满意,我的示例均使用了第三方类库bluebird

var fs = require(‘fs‘)
var Promise = require(‘bluebird‘)
//改造fs.readFile为Promise版本
    var readFileAsync = function(path){
        //返回一个Promise对象,初始状态pending
        return new Promise(function(fulfill, reject){
        fs.readFile(path,  ‘utf8‘, function(err, content){
            //由pending状态进入rejected状态
            if(err)return reject(err)
            //由pending状态进入fulfilled状态
            return fulfill(content)
        })
    })
    }
    //开始使用,调用其then方法,回调接受执行成功的返回值
    readFileAsync(‘./promise-1.js‘).then(function(content){
    console.log(content)
    })

看了上面的代码以后,是不是觉得Promises其实并不复杂呢。

OK,我们继续延续上面的代码,来简单比较一下传统回调和Promises的使用上的差别:

/*
* 简单比较一下传统方式和Promises方式
* 需求:读取两个文件并打印内容
* */
     //callbacks
    fs.readFile(‘./promise-1.js‘, ‘utf8‘, function(err, content1){
        //嵌套一次
        console.log(‘#‘, content1)
        fs.readFile(‘./promise-1.js‘, ‘utf8‘, function(err, content2){
            //第二次嵌套
            console.log(‘##‘, content2)
        })
    })
    //Promises
    readFileAsync(‘./promise-1.js‘).then(function(content1){
        console.log(‘#‘, content1)
        //这里返回一个Promise对象
        return readFileAsync(‘./promiscuitye-1.js‘)
    }).then(function(content2){
        console.log(‘##‘, content2)
    })

上面的代码都没有错误处理,这是一个后果很严重的坏习惯。不过今天我们的重点不在这里,而是分析上下两段代码的主要区别。

第一段代码是传统的嵌套回调,在第二次打印的时候已经使用了两次缩进,而Promises链式调用then方法成功地避免了一次缩进(嵌套),维持了代码结构的相对平坦。上面的代码略显简陋,如果再加上错误处理,Promises毫无疑问将会大放光彩,有兴趣请关注后续章节。

本章写到这里就结束了,相信大家已经对Promises的有了一个初步认识。规范文档往往很难理解,我没有过多的描述规范,因为我相信代码最能够解释一切。不过对规范文档有兴趣的可以自行阅读参考链接。

最后我想强调的一点就是:Promises这种维持代码结构平坦的魔力在业务逻辑复杂多变的情况下是非常有用的

参考链接



未完待续(2014-06-28 00:5

初识JavaScript Promises

时间: 2024-10-05 14:40:41

初识JavaScript Promises的相关文章

笔记一、初识 Javascript

一.初识 Javascript javascript是一种专为与网页交互儿设计的脚本语言.由三部分组成:ECMAScript  (ECMA-262定义) : 提供核心语言功能文档对象模型(DOM): 提供访问和操作网页内容的方法和接口浏览器对象模型(BOM): 提供与浏览器交互的方法和接口Javascript的这三个组成部分在当前五大主流浏览器中都得到了不同程度的支持(IE.FireFox.Chrome.Safari.Opera).基本所有的浏览器都大体上支持ECMAScript第三版.但是对于

javascript基础——初识javascript

每一门语言的学习都是从HelloWorld开始的,我今天也遵循这个原则吧!先上一段代码,认识一下javascript <html><head><title>初识javascript</title><script language="javascript" type="text/javascript"><!--alert("Hello World Wide Web!")//-->

第一讲:初识JavaScript

1.0. 学习目标 –了解javascript组成部分 –认识javascript解析机制 –如何使用javascript 1.1.初识JavaScript •javascript是一种专为与网页交互儿设计的脚本语言.由三部分组成: –ECMAScript  (ECMA-262定义)  提供核心语言功能 –文档对象模型(DOM)提供访问和操作网页内容的方法和接口 –浏览器对象模型(BOM)提供与浏览器交互的方法和接口 •Javascript的这三个组成部分在当前五大主流浏览器中都得到了不同程度的

初始JavaScript Promises之二

初始JavaScript Promises之二 上一篇我们初步学习了JavaScript Promises,本篇将介绍Promise如何优雅地进行错误处理以及提升操作node.js风格1的异步方法的逼格,没错就是使用promisify2. 异步编程中的错误处理 人性的.理想的也正如很多编程语言中已经实现的错误处理方式应该是这样: try {     var val = JSON.parse(fs.readFileSync("file.json")); }catch(SyntaxErro

初识 javascript

第一次接触javascript是在网上看教程时,看到有关DOM操作的内容而认识的.刚开始一直误以为javascript是java的一个子集.因为也没有对javascript有很深的理解,所有就没有去深究javascript和java之间的关系.直到最近才发现,我的这个观点是完全错误的.javascript和java是完全不同的两门语言. 以下内容均源自网络: 1 首先,这两个家伙没有任何的血缘关系,java是是由Sun 公司于1995年5月推出的, 2 而javascript是于1995年由Ne

转:JavaScript Promises相当酷:一种有趣的方案库

许多的语言,为了将异步模式处理得更像平常的顺序,都包含一种有趣的方案库,它们被称之为promises,deferreds,或者futures.JavaScript的promises ,可以促进关注点分离,以代替紧密耦合的接口. 本文讲的是基于Promises/A 标准的JavaScript promises.[http://wiki.commonjs.org/wiki/Promises/A]Promise的用例: 执行规则 多个远程验证 超时处理 远程数据请求 动画 将事件逻辑从应用逻辑中解耦

Day15 HTML补充、初识JavaScript

一.上节回顾 上节回顾: HTML 头部信息:编码.title.style.link(导入css文件) 身体: 内联 块级 --->inline-block(既有内联效果又有块级效果) a标签: target.href(跳转到url,#i1(id=i1跳转到顶部)) img标签: src alt iframe(伪Ajax,上传文件) src form标签 action提交url:method提交方式:get和post:上传文件:enctype="multipart/form-data&qu

《前端之路》之 初识 JavaScript

01 初识 JavaScript 作为在码农圈混迹了 四五年的老码畜来说,学习一门新的语言,就仿佛是老司机开新车一样 轻车熟路. 为什么会这么快呢? 因为各种套路啊- 任何一种计算机语言的最开始都是和 数据类型 这个东西分不开,那么今天,我们就从 JavaScript 的数据类型开始 一.JavaScript 的数据类型 因为对于很多的 jser 的初学者而言,或者说说对于很多代码初学者而言,数据类型是让人疑惑的地方.那么一定要解除这个疑虑. JavaScript 一共有 八种数据类型.其中包含

Javascript Promises

Javascript Promises 2018-11-05 THUDM team Eunbi Choi Syntax new Promise( /* executor */ function(resolve, reject) { ... } ); executor: A function that is passed with the arguments resolve and reject. The executor function is executed immediately by t