关于kintone.Promise的常见写法请参考kintone的Promise基本写法。
本次介绍于2015年7月升级时新增的kintone API的Promise。
为什么需要支持kintone API的Promise呢
新增该功能的理由主要有以下2个。
其一:标准API无法发送同步请求的问题
之前如果是想在获取其他应用的数据之后,使用这些数据进行一些处理,基本上是使用XMLHttpRequest进行痛苦的同步处理。为什么呢?因为kintone请求类的标准API全都是异步处理。
使用XMLHttpRequest的同步请求具有以下缺点。
JavaScript执行同步请求时,执行请求的页面会卡住,不能进行其他操作。
浏览器会提示警告不推荐此方法。(FireFox将来还打算废除XMLHttpRequest。详情请参考此处。)
虽说不推荐,但又不得不使用,为这个而苦恼的人应该不少吧…
其二:使用submit等事件句柄时不能使用请求类kintone API的问题
请求类kintone API的话比如有kintone.api及kintone.proxy等,基本上都是异步处理的。也就是说按下记录添加页面的保存按钮时,不等待kintone.api及kintone.proxy等的执行结果,而直接执行保存。
为了解决上面的问题,于2015年7月版本升级时推出了kintone API的Promise。
(关于Promise的概念,可以参考这里。)
总结kintone JavaScript API 的变更点
可支持Promise的kintone JavaScript API的事件句柄和请求类API如下。
支持Promise的事件
请参考“添加事件句柄”的“handler(event)”.
支持Promise请求类API
kintone.api
kintone.proxy
kintone.plugin.app.proxy
那么,有了这些将会有哪些变化呢?
支持Promise的事件,其返回值可return Promise对象
请求类API如果省略了callback,将返回Promise对象
就是以上这些啦!
应该有人会说:“恩…还是不太理解呢!”。那么你只要记住使用了这个,可以有以下好处就行了。
可以起到跟XMLHttpRequest的同步请求同等效果,因此就不需要XMLHttpRequest了
在事件句柄内使用Promise时可进行任意的异步处理
也就是说可以避免一开始时提到的同步请求的缺点。另外,可在事件句柄内放任意的异步处理。也就是说比如在添加记录的同时可以插入其他应用内的信息了。
修改范例代码
这次就举添加记录时自动编号(暂无中文页面)的sample.js作为例子,根据API文档来修改代码。
sample.js(kintone.Promise对应版)
(function() { "use strict"; // 记录添加、编辑页面显示前的处理 var eventsShow = ['app.record.create.show', 'app.record.edit.show', 'app.record.index.edit.show']; kintone.events.on(eventsShow, function(event) { var record = event.record; if (('app.record.create.show').indexOf(event.type) >= 0) { record['No']['value'] = ""; } record['No']['disabled'] = true; return event; }); // 记录添加页面保存前的处理 kintone.events.on('app.record.create.submit', function(event) { var recNo = 1; var record = event.record; var m = moment(); var params = { 'app': kintone.app.getId(), 'query': 'limit 1', 'fields': ['$id'] }; return new kintone.Promise(function(resolve, reject) { kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params, function(resp) { if (resp.records[0] !== null) { recNo = parseInt(resp.records[0]['$id'].value, 10) + 1; } else { event.error = '无法获取报价编号。'; } //自动编号赋值给报价编号 var autoEstNo = m.format('YYYYMMDD') + "-E" + ('000' + recNo).slice(-3); alert("添加报价编号 " + autoEstNo); record['No']['value'] = autoEstNo; resolve(event); }, function() { record['No'].error = '无法获取报价编号。'; resolve(event); }); }); }); })();
重点:
根据“支持Promise的事件,其返回值可return Promise对象”修改相应的代码
在事件句柄内,return回来的Promise对象处理完后再继续后面的处理。因此使用kintone.api可进行异步处理
不需要写同步请求
撰写该文章的时候(2015年7月),IE不能处理一般的Promise对象。但是,kintone.Promise竟然在IE上也可以使用!开发时无需考虑浏览器的种类了。
另外,上面的示例如果省略了kintone.api的回调函数,会返回Promise对象。因此,可以像下面这样写。
sample.js(kintone.api 回调函数省略版)
(function() { "use strict"; // 记录添加、编辑页面显示前的处理 var eventsShow = ['app.record.create.show', 'app.record.edit.show', 'app.record.index.edit.show']; kintone.events.on(eventsShow, function(event) { var record = event.record; if (('app.record.create.show').indexOf(event.type) >= 0) { record['No']['value'] = ""; } record['No']['disabled'] = true; return event; }); // 记录添加页面保存前的处理 kintone.events.on('app.record.create.submit', function(event) { var recNo = 1; var record = event.record; var m = moment(); var params = { 'app': kintone.app.getId(), 'query': 'limit 1', 'fields': ['$id'] }; return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then(function(resp) { if (resp.records[0] !== null) { recNo = parseInt(resp.records[0]['$id'].value, 10) + 1; } else { event.error = '无法获取报价编号。'; } //自动编号赋值给报价编号 var autoEstNo = m.format('YYYYMMDD') + "-E" + ('000' + recNo).slice(-3); alert("添加报价编号 " + autoEstNo); record['No']['value'] = autoEstNo; return event; }, function(resp) { record['No'].error = '无法获取报价编号。'; return event; }); }); })();
重点:
根据“请求类API如果省略了callback,将返回Promise对象”修改了相应的代码
使用kintone.api或kintone.proxy时,无需每次都要写 "new kintone.Promise()"来生成新的Promise对象
※上面的示例更改后的运行结果跟更改前的完全一样,因此省略截图。
最后
关于新增kintone.Promise的背景及其使用方法,大家是否有所了解了。虽然有点复杂,但是使用这个可以让你的kintone自定义更加得心应手。请务必尝试一下哦!
该Tips在2015年7月版中进行过确认。
回复(2)
这篇暂时只有日文的,打不开可能是因为网络的原因。多试几次。
添加记录时自动编号 这个应用打不开