10月阅读周·JavaScript异步编程设计快速响应的网络应用:用Promise对象代替回调函数

举报
叶一一 发表于 2024/10/22 09:43:53 2024/10/22
【摘要】 背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。这个“玩法”虽然常见且板正,但是有效,已经坚持阅读九个月。已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScri...

背景

去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。

没有计划的阅读,收效甚微。

新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。

这个“玩法”虽然常见且板正,但是有效,已经坚持阅读九个月。

已读完书籍《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》、《JavaScript权威指南》

当前阅读周书籍《JavaScript异步编程设计快速响应的网络应用》

用Promise对象代替回调函数

理想情况下,开始执行异步任务的任何函数都应该返回Promise对象。遗憾的是,大多数JavaScript API(包括所有浏览器及Node.js均使用的那些原生函数)都基于回调函数,而不是基于Promise对象。在本节中,我们将看到如何在基于回调函数的API中使用Promise对象。

在基于回调函数的API中使用Promise对象的最直接的方法是,生成一个Deferred对象并传递其触发器函数作为API的回调参数。例如,我们可以把Deferred对象的resolve方法传递给一个像setTimeout这样的简单异步函数。

var timing = new $.Deferred();
setTimeout(timing.resolve, 500);

考虑到API可能会出错,我们还要写一个根据情况指向 resolve 或reject的回调函数。例如,我们会这样写Node风格的回调:

var fileReading = new $.Deferred();
fs.readFile(filename, 'utf8', function (err) {
  if (err) {
    fileReading.reject(err);
  } else {
    fileReading.resolve(Array.prototype.slice.call(arguments, 1));
  }
});

(没错,确实能在Node中使用jQuery。只要运行命令行npm install jquery即可,其用法和其他所有模块一样。还有一个库叫Standalone Deferred,它独立实现了jQuery风格的Promise。

总这么写很麻烦,所以何不写一个工具函数以根据任何给定Deferred对象来生成Node风格的回调呢?

deferredCallback = function (deferred) {
  return function (err) {
    if (err) {
      deferred.reject(err);
    } else {
      deferred.resolve(Array.prototype.slice.call(arguments, 1));
    }
  };
};

有了这个工具函数,前面那个例子就可以写成这样:

var fileReading = new $.Deferred();
fs.readFile(filename, 'utf8', deferredCallback(fileReading));

Q.js的Deferred对象为此提供了一个现成的node方法:

var fileReading = Q.defer();
fs.readFile(filename, 'utf8', fileReading.node());

随着Promise越来越流行,会有越来越多的JavaScript库循着jQuery的脚步,要求其异步函数必须返回Promise对象。到那时,只需要几行代码就能将想用的任何异步函数转变成Promise对象的生成函数。

总结

Promise 大大有助于让意面式的回调趋于平滑(富含Ajax 调用的应用通常充斥着这些如意大利面条般纠缠在一起的回调),而且也是因为Promise可以非常轻松地协调各种类型的异步任务。

运用Promise需要一些实践经验,特别是使用 pipe 时,不过这是非常值得培养的一种习惯。你可以在此窥见 JavaScript 的未来。返回Promise对象的JavaScriptAPI越多,这些API就越有吸引力。


作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。