本次学习 kityminder save 功能.
回顾 core/data.js:
// 注册一个(用于导入/导出的)协议. exports.registerProtocol = function(name, protocol) { _protocols[name] = protocol; // 放到一个集合中. } extend class Minder { exportJson(): // 导出当前脑图数据为 JSON 对象. // 方法是从根节点开始递归所有节点, 每个节点导出为一个 json 对象, 子节点组成一个数组. importNode(node, json): // 根据 json 数据转换成脑图节点. exportData(protocol_name, option): // 使用指定协议导出, 一会研究细节. importData(protocol_name, data, option): // 使用指定协议导入. }
协议的注册/获取比较简单. 由于 json 格式比较容易, 我们不如先研究 json 格式的 protocol.
找到 protocol/json.js 查看, 果然十分简单:
// 注册名为 'json' 的导入/导出协议. data.registerProtocol('json', { fileDescription: 'KityMinder 格式', // 格式名. fileExtension: '.km', // 文件后缀. ... dataType, mineType (应是 mime 拼写错?) 略... encode(json): // 编码函数, 对象->字符串. 使用内建 JSON 对象实现. decode(local): // 解码函数, 字符串->对象. });
这里重点是提供了 encode(), decode() 两个函数, 分别对应导出, 导入. 如果未提供 decode(), 就表示不支持导入.
现在再细看 exportData(protocol-name, option) 方法, 步骤大致是:
Minder.prototype.exportData = function(protocol_name, option) { // 第一步先导出为 json 格式. var json = this.exportJson(); // 如果指定了 protocol_name, 则检查该协议, 及是否支持导出. if (protocol_name) ... // 不支持则抛出异常. // 发布 'before-export' 事件. this.fire('beforeexport', ...); // 导出为指定格式数据. var encoded_data = protocol.encode(json, ...); return Promise.resolve(encoded_data); // 此调用暂时不明 }
如果忽略掉 Promise, 则其它都简单易解. 我们在 console 中试着使用此函数, 可看到结果:
这样, 如果我们要开发将数据存到 localStorage 或服务器上的功能, 只需使用 exportJson() 或 exportData()
将数据导出为 json 格式即可. 其它格式可选.
以前曾经忽略的 promise 不弄明白是不行啊, 总是跳出来挡路, 那今天就去查查它是做什么的.
打开 core/promise.js, 里面注释写着 Thenable - Embedded Minimum Strictly-Compliant Promises.
源码位于 http://github.com/rse/thenable, 让我们去找找有没有文档. 顺便找到一个不错的中文介绍:http://www.csdn.net/article/2014-05-28/2819979-JavaScript-Promise
看起来是为了解决多个回调(callback) 组成的金字塔(层层回调)问题.
认识一下 Promise/A+ 规范:
1. 一个 promise 可能有三种状态: 等待 (pending), 已完成 (fulfilled), 已拒绝(rejected)
2. 状态只能从 pending->fulfilled|rejected, 不能其它转换, 也不能逆向转换.
3. promise 必须实现 then 方法, 而且 then 必须返回一个 promise ...
4. then 方法接受两个参数: on_success, on_error: 成功时回调, 失败时回调.
使用示例:
function run() { getData('abc.json') .then(handle_json) // 返回一个 thenable 的对象 .then(sleep(300)) .then(show_next); }
后面看到重点, 现今流行的各大 js 库, 几乎都不同程度的实现了 Promise, 只是暴露出来的大都是 Deferred 对象.
原来 Promise 是 Deferred 换了个名字么?
优点: Promise 用法很简单, 组织的代码很清晰, 从此不用再受 callback 的折磨了.
看来有空要多看类库源码......