一起来挑战一下kintone API的Promise吧!

aki发表于:2017年03月08日 13:01:59更新于:2019年11月12日 10:02:24

关于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月版中进行过确认。

相关Tips

回复(2)

  • betsy_yan

    这篇暂时只有日文的,打不开可能是因为网络的原因。多试几次。

    引用 yzx 的回复:

    添加记录时自动编号  这个应用打不开

  • yzx

    添加记录时自动编号  这个应用打不开