javascript下使用Promise封装FileReader


Posted in Javascript onFebruary 19, 2016

Promise 在处理异步的时候是个很好的选择,可以减少嵌套层次,让代码更好读,逻辑更清晰。ES6 将其加入规范,jQuery 3.0 也修改实现向规范靠拢(3.0 发布公告)。一些新增元素比如 .fetch() 原生就 “thenable”,不过大多数以往的 API 还要依赖回调,这个时候,我们只要将它们重新封装,就能避开嵌套陷阱,享受 Promise 带来的愉悦体验。

Promise 一般用法
先来看下 Promise 的一般用法。

// 声明 Promise 对象
var p = new Promise(function (resolve, reject) {
 // 不管啥时候,该执行then了,就调用 resolve
 setTimeout(function () { 
  resolve(1);
 }, 5000);

 // 或者不管啥问题,就调用 reject
 if (somethingWrong) {
  reject('2');
 }   
});
  
// 使用 Promise 对象
p.then(function (num) {
 // 对应上面的 resolve
 console.log(num); // 1
}, function (num) {
 // 对应上面的 reject
 console.log(num); // 2
});

Promise 的驱动模型并不复杂:任何操作,假定它只有两个结果,成功或者失败。那么只需要在合适的时间调用合适的程序,进入合适的后续步骤即可。.then() 顾名思义,就是下一步的意思,当前面的 Promise 有了结果——即调用 resolve 或者 reject——之后,就启动对应的处理函数。

Promise 实例创建后就会开始执行,判定结果需要我们自己来,比如加载成功,或者满足某个条件,等等。通过串联 .then() 则可以完成一系列操作。每次调用 .then() 都会创建一个新的 Promise 实例,它会静静等待前面的实例状态改变后再开始执行。

封装 FileReader
接下来开始封装。思路很简单,FileReader 除了提供各种 read 方法,还有几个事件钩子,其中 onerror 和 onload 很明显可以作为判断任务是否完成的依据。加载成功的话,就需要用到文件内容,所以将文件或文件内容传递到下一步也十分必要。

最后完成的代码如下:

function reader (file, options) {
 options = options || {};
 return new Promise(function (resolve, reject) {
  let reader = new FileReader();

  reader.onload = function () {
   resolve(reader);
  };
  reader.onerror = reject;

  if (options.accept && !new RegExp(options.accept).test(file.type)) {
   reject({
    code: 1,
    msg: 'wrong file type'
   });
  }

  if (!file.type || /^text\//i.test(file.type)) {
   reader.readAsText(file);
  } else {
   reader.readAsDataURL(file);
  }
 });
}

为了能真正派上用场,里面还有一些验证文件类型的操作,不过跟本文主旨无关,略过不表。这段代码的核心是创建一个 Promise 对象,等待 FileReader 读取完成后调用 resolve 方法,或者出现问题时调用 reject 方法。

使用刚才封装好的函数
接下来就可以在项目中使用了:

reader(file)
 .then(function (reader) {
  console.log(reader.result);
 })
 .catch(function (error) {
  console.log(error);
 });

.then() 支持两个参数,第一个在 Promise 成功时启动,第二个自然在失败时启动。用 .catch() 可以实现同样地效果。Promise 的好处除了可读性更佳以外,返回的 Promise 对象还可以任意传递,继续进行链式调用,有很大想象空间。

继续 .then()
于是我们不妨串联更多操作(本来想写个断点续传的,回头再说吧):

全选复制放进笔记reader(file)

.then(function (reader) {
  return new Promise(function (resolve, reject) {
   // 就随便暂停个5秒吧……
   setTimeout(function () {
    resolve(reader.result); 
   }, 5000);
  });
 })
 .then(function (content) {
  console.log(content);
 });

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
Jun 18 Javascript
Javascript中自动切换焦点实现代码
Dec 15 Javascript
基于javascipt-dom编程 table对象的使用
Apr 22 Javascript
jquery简单的弹出层浮动层代码
Apr 27 Javascript
jquery实现超简洁的TAB选项卡效果代码
Aug 28 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
Jan 31 Javascript
浅谈JS之iframe中的窗口
Sep 13 Javascript
Bootstrap字体图标无法正常显示的解决方法
Oct 08 Javascript
AngularJS 防止页面闪烁的方法
Mar 09 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
Mar 17 Javascript
JS简单获取当前日期时间的方法(如:2017-03-29 11:41:10 星期四)
Mar 29 Javascript
微信小程序scroll-view仿拼多多横向滑动滚动条
Apr 21 Javascript
javascript每日必学之循环
Feb 19 #Javascript
jQuery实现简单的DIV拖动效果
Feb 19 #Javascript
JavaScript深度复制(deep clone)的实现方法
Feb 19 #Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
Feb 19 #Javascript
基于JavaScript实现弹出框效果
Feb 19 #Javascript
jQuery on()绑定动态元素出现的问题小结
Feb 19 #Javascript
学习javascript文件加载优化
Feb 19 #Javascript
You might like
php学习笔记 [预定义数组(超全局数组)]
2011/06/09 PHP
解析php DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
php文档工具PHP Documentor安装与使用方法
2016/01/25 PHP
PHP给文字内容中的关键字进行套红处理
2016/04/12 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
js输出列表实现代码
2010/09/12 Javascript
Javascript 倒计时源代码.(时.分.秒) 详细注释版
2011/05/09 Javascript
js选取多个或单个元素的实现代码(用class)
2012/08/22 Javascript
js中replace的用法总结
2013/12/27 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
2014/09/28 Javascript
js实现时间显示几天前、几小时前或者几分钟前的方法集锦
2015/05/29 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
2015/06/19 Javascript
js实现滚动条滚动到某个位置便自动定位某个tr
2021/01/20 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
2017/01/04 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
Node.js简单入门前传
2017/08/21 Javascript
微信小程序左右滑动的实现代码
2017/12/15 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
JavaScript键盘事件响应顺序详解
2019/09/30 Javascript
基于ts的动态接口数据配置的详解
2019/12/18 Javascript
通过python下载FTP上的文件夹的实现代码
2013/02/10 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
Python正则表达式匹配数字和小数的方法
2019/07/03 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
html5 canvas 使用示例
2010/10/22 HTML / CSS
荷兰网上鞋店:Ziengs.nl
2017/01/02 全球购物
ASOS英国官网:英国在线时装和化妆品零售商
2017/05/19 全球购物
美国打印机墨水和碳粉购物网站:QuikShip Toner
2018/08/29 全球购物
华为c/c++笔试题
2016/01/25 面试题
中班幼儿评语大全
2014/04/30 职场文书
小学体育组工作总结
2015/08/13 职场文书
2019年最新版见习人员管理制度!
2019/07/08 职场文书
Go语言的协程上下文的几个方法和用法
2022/04/11 Golang