举例详解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的inArray 方法介绍
Oct 08 Javascript
javascript实现颜色渐变的方法
Oct 30 Javascript
JS 去除Array中的null值示例代码
Nov 20 Javascript
分享两段简单的JS代码防止SQL注入
Apr 12 Javascript
非常酷炫的Bootstrap图片轮播动画
May 27 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
Aug 14 jQuery
js 倒计时(高效率服务器时间同步)
Sep 12 Javascript
ES6中Array.find()和findIndex()函数的用法详解
Sep 16 Javascript
详解vue中引入stylus及报错解决方法
Sep 22 Javascript
Node.js JSON模块用法实例分析
Jan 04 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
Apr 14 Javascript
vue element和nuxt的使用技巧分享
Jan 14 Vue.js
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
php网上商城购物车设计代码分享
2012/02/15 PHP
几行代码轻松实现PHP文件打包下载zip
2017/03/01 PHP
Laravel框架实现的记录SQL日志功能示例
2018/06/19 PHP
PHP PDOStatement::fetch讲解
2019/01/31 PHP
struts2 jquery 打造无限层次的树
2009/10/23 Javascript
JavaScript(JS) 压缩 / 混淆 / 格式化 批处理工具
2010/12/10 Javascript
javascript 实现简单的table排序及table操作练习
2012/12/28 Javascript
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
Angular浏览器插件Batarang介绍及使用
2018/02/07 Javascript
详解微信小程序开发(项目从零开始)
2019/06/06 Javascript
jQuery实现html可联动的百分比进度条
2020/03/26 jQuery
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
[50:58]2018DOTA2亚洲邀请赛3月29日 小组赛A组OpTic VS Newbee
2018/03/30 DOTA
python中使用OpenCV进行人脸检测的例子
2014/04/18 Python
Django的session中对于用户验证的支持
2015/07/23 Python
Python编程之event对象的用法实例分析
2017/03/23 Python
Python中input与raw_input 之间的比较
2017/08/20 Python
Python实现的多项式拟合功能示例【基于matplotlib】
2018/05/15 Python
python 从文件夹抽取图片另存的方法
2018/12/04 Python
django的settings中设置中文支持的实现
2019/04/28 Python
解决Pytorch训练过程中loss不下降的问题
2020/01/02 Python
Pytorch模型转onnx模型实例
2020/01/15 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
巴西箱包、背包、钱包和旅行配件购物网站:Inovathi
2019/12/14 全球购物
护理学专业推荐信
2013/12/03 职场文书
美术毕业生求职信
2014/02/25 职场文书
网络技术专业求职信
2014/07/13 职场文书
导游词怎么写
2015/02/04 职场文书
2015年清明节活动总结
2015/02/09 职场文书
2015公司年度工作总结
2015/05/14 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
Python 流媒体播放器的实现(基于VLC)
2021/04/28 Python