举例详解JavaScript中Promise的使用


Posted in Javascript onJune 24, 2015

摘录 ? Parse JavaScript SDK现在提供了支持大多数异步方法的兼容jquery的Promises模式,那么这意味着什么呢,读完下文你就了解了。

“Promises” 代表着在javascript程序里下一个伟大的范式,但是理解他们为什么如此伟大不是件简单的事。它的核心就是一个promise代表一个任务结果,这个任务有可能完成有可能没完成。Promise模式唯一需要的一个接口是调用then方法,它可以用来注册当promise完成或者失败时调用的回调函数,这在CommonJS Promises/A proposal.大体讲到了。比如,我想保存一个Prase.Object对象,这是个异步操作,在旧的回调范式中,你的代码可能这样写:
 

object.save({ key: value }, {
 success:function(object) {
  // the object was saved.
 },
 error:function(object, error) {
  // saving the object failed.
 }
});
在新的Promise范式中,同样的代码你可以这样写:
 
object.save({ key: value }).then(
 function(object) {
  // the object was saved.
 },
 function(error) {
  // saving the object failed.
 });

没有多大的区别?那么有啥大不了的地方呢?好吧,promises的真正强大之处在于多重的链接,当调用promise.then(func)时返回一个新的promise,它不会执行直到上一个完成。但是这里有一种特殊的情况,如果我的回调通过then返回一个新的promise,那么通过then返回的promise将不会执行,直到回调执行完成。详细细节请参考 Promises/A+,这是个复杂的规则,通过例子我们能更清楚的认识下.

假设你写了段登陆的代码,查找对象然后更新它。在旧的回调范式中,你可以使用金字塔式的代码完成:
 

Parse.User.logIn("user","pass", {
 success:function(user) {
  query.find({
   success:function(results) {
    results[0].save({ key: value }, {
     success:function(result) {
      // the object was saved.
     }
    });
   }
  });
 }
});

这看起来已经很可笑,更可笑的是甚至没有任何错误处理。但是promise链式的结构,使代码看起来更舒服了:
 

Parse.User.logIn("user","pass").then(function(user) {
 returnquery.find();
}).then(function(results) {
 returnresults[0].save({ key: value });
}).then(function(result) {
 // the object was saved.
});

哇!好多啦!

错误处理

上面的代码简单期间没有添加错误处理,但是添加了后你会发现在旧的回调代码中一团糟:
 

Parse.User.logIn("user","pass", {
 success:function(user) {
  query.find({
   success:function(results) {
    results[0].save({ key: value }, {
     success:function(result) {
      // the object was saved.
     },
     error:function(result, error) {
      // An error occurred.
     }
    });
   },
   error:function(error) {
    // An error occurred.
   }
  });
 },
 error:function(user, error) {
  // An error occurred.
 }
});

由于promises知道处理是否完成,它可以传递错误,不执行任何回调直到遇到错误。比如,上面的代码可以简写为:
 

Parse.User.logIn("user","pass").then(function(user) {
 returnquery.find();
}).then(function(results) {
 returnresults[0].save({ key: value });
}).then(function(result) {
 // the object was saved.
},function(error) {
 // there was some error.
});

通常,开发者认为一个异步的promise失败等同于抛出一个异常。事实上,如果一个回调抛出一个错误,promise将返回失败信息。把错误传递到下一个可用的错误处理器等同于抛出一次异常直到捕获处理。

jQuery, Backbone, 和 Parse

有很多实现了promises的库供开发者可用。 像jQuery的 Deferred, 微软的 WinJS.Promise, when.js, q, 和dojo.Deferred.

然而,有个有趣的地方需要了解。 你可以在这里读到 long and fascinating jQuery pull request discussion, jQuery的实现没有完全按照Promises/A的规则来,很多地方用了其他实现方式,实验时,我发现只有一个地方不太一样。如果一个错误处理器返回一些其他的信息,而不单纯返回一个promise,大多数实现会考虑处理这个错误,不做错误传递。然而,jquery不认为在此处处理这个错误,而是把它向前传递。虽然,来自不同系统的promise应该能无缝的混合使用,但是你还是应当注意些。一个潜在的问题是会在错误处理器中返回promises(替换原始数值),因为它们会被同等对待。
 

doFailingAsync().then(function() {
 // doFailingAsync doesn't succeed.
},function(error) {
 // Try to handle the error.
 return"It's all good.";
}).then(function(result) {
 // Non-jQuery implementations will reach this with result === "It's all good.".
},function(error) {
 // jQuery will reach this with error === "It's all good.".
});

 
在 Backbone 0.9.10最新版本中,异步方法现在返回一个 jqXHR,这是jquery promise的一种类型。Parse JavaScript SDK的一个目标是尽可能的和Backbone兼容,我们不能返回一个jqXHR,因为它在 Cloud Code上不能很好地工作,因此,我们不都添加一个 Parse.Promise类,它遵照jQuery Deferred的标准。 Parse JavaScript SDK最新版本已经更新了所有的异步方法来支持这些新的对象,旧的回调方法仍然可用。但是基于上面列出的例子,我相信你更喜欢新的方式。所以试试promises吧!

Javascript 相关文章推荐
jQuery 使用手册(二)
Sep 23 Javascript
详谈 Jquery Ajax异步处理Json数据.
Sep 09 Javascript
firefox下jquery ajax返回object XMLDocument处理方法
Jan 26 Javascript
js原型继承的两种方法对比介绍
Mar 30 Javascript
JS判断字符串变量是否含有某个字串的实现方法
Jun 03 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
原生js轮播特效
May 18 Javascript
jQuery序列化后的表单值转换成Json
Jun 16 jQuery
js实现图片旋转 js滚动鼠标中间对图片放大缩小
Jul 05 Javascript
vue-cli 打包后提交到线上出现 "Uncaught SyntaxError:Unexpected token" 报错
Nov 06 Javascript
vue请求数据的三种方式
Mar 04 Javascript
Vue路由 重定向和别名的区别说明
Sep 09 Javascript
jQuery对JSON数据进行排序输出的方法
Jun 24 #Javascript
jQuery中$.extend()用法实例
Jun 24 #Javascript
深入理解JavaScript编程中的同步与异步机制
Jun 24 #Javascript
详解JavaScript中的客户端消息框架设计原理
Jun 24 #Javascript
jquery实现从数组移除指定的值
Jun 24 #Javascript
浅谈关于JavaScript API设计的一些建议和准则
Jun 24 #Javascript
详解JavaScript的策略模式编程
Jun 24 #Javascript
You might like
收听短波不可能有声音清晰的品质吗
2021/03/01 无线电
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
php 中奖概率算法实现代码
2017/01/25 PHP
PHP从数组中删除元素的四种方法实例
2017/05/12 PHP
JS提交并解析后台返回的XML的代码
2008/11/03 Javascript
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
Js base64 加密解密介绍
2013/10/11 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
JS操作CSS随机改变网页背景实现思路
2014/03/10 Javascript
jquery.ajax之beforeSend方法使用介绍
2014/12/08 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
Map.vue基于百度地图组件重构笔记分享
2017/04/17 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
解决iView中时间控件选择的时间总是少一天的问题
2018/03/15 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
layui使用label标签的方法
2019/09/14 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
Python装饰器实现几类验证功能做法实例
2017/05/18 Python
Python 稀疏矩阵-sparse 存储和转换
2017/05/27 Python
Python3实现转换Image图片格式
2018/06/21 Python
Python 打印中文字符的三种方法
2018/08/14 Python
Pytoch之torchvision.transforms图像变换实例
2019/12/30 Python
python多进程 主进程和子进程间共享和不共享全局变量实例
2020/04/25 Python
3种适用于Python的疯狂秘密武器及原因解析
2020/04/29 Python
Python实现发票自动校核微信机器人的方法
2020/05/22 Python
在keras里实现自定义上采样层
2020/06/28 Python
4款Python 类型检查工具,你选择哪个呢?
2020/10/30 Python
Pandas数据分析的一些常用小技巧
2021/02/07 Python
日本订房网站,预订日本星级酒店/温泉旅馆:Relux(支持中文)
2020/01/03 全球购物
华美博弈C/VC工程师笔试试题
2012/07/16 面试题
餐厅感恩节活动策划方案
2014/10/11 职场文书
迟到检讨书范文
2015/01/27 职场文书
高中政治教学反思
2016/02/23 职场文书
MySQL三种方式实现递归查询
2022/04/18 MySQL