同步第三方平台订单数据时的问题及对策

窦新 发布于 2016年06月13日
无人欣赏。

背景

最近做个独立项目,需要从一个第三方平台的 API 获取订单数据,但是该平台的 API 只能返回类似下面格式的数据

{ data: { count: 100000, items: [ { _id: "575d74b6427b9e8f40d5b619", num_iid: 1, name: "0", __v: 0 }, { _id: "575d74b6427b9e8f40d5b61a", num_iid: 2, name: "1", __v: 0 }] } }

上面这个数据是我测试生成的,其中 num_iid 是该平台唯一的,可以关联到商品记录,现在我需要把这个数据同步到我的系统上进行处理,那么这里面有这几个问题:

1. 第三方平台的数据可能随时更新,比如订单的状态
2. 该平台并不提供更新订阅的接口,所以订单是否更新了,我的系统并不知道
3. 该平台除了这个接口,还有一个根据订单 id 获取订单详情的接口

我的系统需要满足:

1. 数据需要和该平台同步
2. 数据的同步可以有半天的延时
3. 目前可以选择最简单的处理,在系统运行过程中去选择优化的办法

技术选择

NodeJS, MongoDB

解决办法

初步是选择了递归来处理,从平台分页获取数据,数据数据后根据平台的 count 来判断后面是否还要数据,如果有,再进行请求,如果没有了,对数据进行处理后返回;这个方案我没有处理好,JS 异步特性没有利用起来,读者朋友可以试下。

最后,选定的方案是:

1. 先给平台发一个请求,获得 **count**
2. 根据 **count** 和我的 **pageSize** 来判定需要多少个请求
3. 组装所有的请求,合并成一个 Array
4. 使用 Promise.all(Array) 来进行处理
5. 最后对结果数据进行下处理,然后同步到数据库

代码示例

封装请求

将获取订单的请求进行封装

``` const Request = require('request');

/** * api request * @param pageNo 页码 * @param pageSize 每页数据量 */ const promiseReq = function(pageNo, pageSize) { const url = http://127.0.0.1:3001/users/list?pageNo=${pageNo}&pageSize=${pageSize}; console.log(start request, pageNo: ${pageNo}, pageSize: ${pageSize}); return new Promise((resolve, reject) => { Request(url, (error, response, body) => { if (!error && response.statusCode === 200) { resolve(JSON.parse(body)); } else { reject(error); } }) }) } ```

合并所有的请求

先发一个小请求,得到订单总量

const pre = yield promiseReq(1, 5); const count = pre.data.count;

判定需要多少个请求

const pageSize = 100; const length = Math.ceil(count / 100);

合并请求

const reqs = []; for (let i = 0; i < 10; i++) { reqs.push(promiseReq(i+1, pageSize)); }

请求

const ret = yield Promise.all(reqs);

数据处理

得到了数据后,进行相应的处理即可

对于数据入库,有 2 个办法:

1. 因为数据是全部拉取回来的,那么本地的纪录可以全部抹去,数据重新入库
2. 通过 **mongoose** 的 **findOneAndUpdate** 来处理,对存在的数据进行更新,不存在的数据进行入库

总结

这个办法利用了 Promise.all() 来处理,因为每个请求都是异步的,所以处理起来速度很快。

但同样也存在一些问题,因为第三方平台的 API 使用会有次数限制,以及每次都大量获取数据,如果订单量比较小没有问题,但如果订单量特别多,这个办法就有很大的优化空间了。

对于后续在运行中可以进行优化,如对于未收货等订单,可以单获取这个订单的状态然后进行更新;根据本地的数据记录,和平台的总量之间计算出增量部分,然后合理处理 pageNo 等

最后,有其他解决办法的朋友,在评论里提出

关注我的微信公众号和微博,第一时间收到文章推送和交流

微信公众号

alt text

微博

alt text

欢迎在分答上直接向我提问

alt text

暂无回复
登录 或者 注册