写在前面的话

  1. 本篇水文发出来之后,有朋友反馈文笔太差,的确是作者的锅,码字水平目前就这么高,只能委屈大家看这篇辣眼睛的文字了,文笔只能慢慢改善。
  2. 还有朋友反馈看懵的,仔细想想也是作者的锅,没有表达清楚,修改重发。
  3. 澄清一下本文和Promise.all没有半毛钱关系,如果让大家误会,见谅。
  4. 有朋友希望快速浏览能有一句总结,不想看代码。这里解释一下,其实总结就包含在下文合并接口的解释里,本文要解决的业务相对比较小众,脱离场景谈总结也没啥意义,不看业务场景和代码,本文真的没有任何的价值,主要是记录开发业务的一个思路。

关于接口合并(不知道有没有专门的术语,暂且如此称呼)在这里解释一下,本文所指的是页面初始化加载数据是一个api接口,而加载更多数据的是另一个api接口,前一个接口肯定会调用,第二个接口不一定会被调用(用户触发),但是我们把两个调用接口封装起来,公用一个业务逻辑,作者比较懒不想给两个接口分别写业务逻辑。

一. 前言

上次作者在个人项目中遇到的post预检请求bug,水了一篇小文《记一次跨域post请求数据之preflight request》,本文也只是记录在特定项目中如何抽取业务逻辑,封装两个api接口公用一段业务逻辑的思路,对读者朋友们有所启发,那就最好不过了,有什么问题或者错漏之处欢迎大家提出来分享,作者此文权当抛砖引玉。

关于接口合并,作者在项目开发文档中也有描述,有兴趣的可以去瞅瞅。

二. 猫眼API接口分析

脱离业务谈编码就是耍流氓。下面简单介绍一下猫眼的接口,其中我们发现在猫眼的两个页面中可以使用接口合并,现在以猫眼正在热映页面的两个api为例。

1 初始化获取当前热映电影列表

以下都将以 api_1 指称 初始化获取当前热映电影列表api接口

1.1说明
信息 说明
功能 初始化获取电影信息
URL //m.maoyan.com/ajax/movieOnInfoList
格式 JSON
HTTP METHOD GET

1.2 请求参数

参数 类型 必选 说明
token String false 登录之后的凭证

1.3返回字段

字段 类型 说明
movieList Array 电影列表(默认一次返回10条)
total Number 电影总数目, total >= movieList.length
movieIds Array 所有电影ID,总数同total,后续请求更多电影时必须依赖它们
coming Array 更多电影列表,第一次请求必定是空

1.4 接口示例

//m.maoyan.com/ajax/movieOnInfoList?token

{"coming": [],"stid": "576591972453269000","movieIds": [247295, 410629, 1206605, 248906, 341139, 1250341, 1218091, 344869, 1243239, 580298, 907653],"movieList": ["同下方获取当前热映更多电影列表接口返回的coming字段"],"stids": [{"movieId": 247295, "stid": "576591972453269000_a247295_c0"}],"total": 11
}
复制代码

2 获取当前热映更多电影列表

以下都将以 api_2指称 获取当前热映更多电影列表api接口

2.1 说明

信息 说明
功能 获取hot更多电影列表
URL //m.maoyan.com/ajax/moreComingList
格式 JSON
HTTP METHOD GET

2.2 请求参数

参数 类型 必选 说明 列子
token String false 登录之后的凭证
movieIds String true 请求的电影ID,依赖初始化接口的接口返回字段movieIds "1214652,1229799,1251606"

2.3 返回字段

字段 类型 说明
coming Array 更多电影列表

2.4 接口示例

//m.maoyan.com/ajax/moreComingList?token=&movieIds=1214652%2C1229799%2C1251606%2C1215114

{"coming": [{"id": 1214652,"comingTitle": "2月22日 周五","globalReleased": true,"haspromotionTag": false,"img": "http://p0.meituan.net/w.h/movie/979266668d0e94dc83956a70d22b4eaa184105.jpg","nm": "朝花夕誓-于离别之朝束起约定之花","preShow": false,"rt": "2019-02-22","sc": "9.2","showInfo": "今天10家影院放映21场","showst": "3","star": "石见舞菜香,入野自由,茅野爱衣","version": "","wish": 76220,"wishst": 0,},...略]
}
复制代码

上面两大坨数据,就是作者整理的api接口文档,仔细观察两个api接口的返回字段,都有一个coming字段,作者最初的灵感也是来自于它们,api_1接口的数据列表放在movieList字段中,我们下面就将以Promise来处理coming和movieList。

有朋友关注api_2接口依赖于api_1接口,猫眼的api就是这么设计的,api_1接口返回了部分电影列表、全部的电影id和电影总数,api_2接口请求只需传递电影id就可以了。其他公司设计的api接口请求参数可能就是offset和limit。

三. 方案

要进行接口合并,无非要解决两个问题, 判断接口、处理数据

1 判断接口

api_2接口请求数据的时候必定需要知道请求的是那些电影的ID,那么我们肯定要在本地定义一个offset作为数据的偏移量,作者的项目是vue写的,就放在了vue的组件实例上了。我们将offset设为0,第一次请求时offset必定为0,我们就将offset的值作为判断接口的依据。

下面直接上代码

/***
*  业务逻辑部分
*  1. isFirst判断是否第一次请求
*  2. getInfoListAction(isFirst) 得到最终的api操作函数 getMovieInfoList
*  关于 getInfoListAction请参看下文 @src src\api\index.js
***/
import { getInfoListAction } from '@/api'const { offset, limit, total } = this
const isFirst = offset === 0
const getMovieInfoList = getInfoListAction(isFirst)
getMovieInfoList(params).then(data => {// ....数据处理此处略,详见下文
})
复制代码

难道直接用if-esle来硬编码判断?作者当然不会这么糊弄大家了。

/**
*  @addr src/api/index.js
*  @ getMovieOnInfoList 初始api的操作函数
*  @ getMoreComingList 加载更多数据的操作函数
*  @ getInfoListAction通过上文的isFirst作为参数调用来判断返回 getMovieOnInfoList还是 getMoreComingList(也就是上文提到的getMovieInfoList)*  关于 getDataByAction 参看下文 @addr src/util/index.js
**/
import request from '@/util/request'
import { getDataByAction } from '@/util'const getMovieOnInfoList = request('/movieOnInfoList')
const getMoreComingList = request('/moreComingList')
export const getInfoListAction = getDataByAction(getMovieOnInfoList, getMoreComingList)/***
*  @addr src/util/index.js
*  @getDataByAction 使用函数柯里化,接受两个操作函数返回一个新函数,在业务逻辑中返回最终的api操作函数
**/
export const getDataByAction = (initAction, nextAction) => (isFirst) => isFirst ? initAction : nextAction// @addr src/util/request.js
import Axios from 'axios'
let baseURL = process.env.VUE_APP_URLconst defaultConfig = {baseURL
}const STATUS_CODE = 200const instance = Axios.create(defaultConfig)const request = (url, method = 'get') => (params) => {return instance({url,method,...params}).then(resp => {if (resp.status === STATUS_CODE) {return resp.data}})
}
export default request
复制代码

请忽略作者的request函数的丑陋封装,没有做错误处理,(逃

2 数据处理

由上文可知,我们最终的api调用函数调用之后其实是返回了一个Promise{<resolve>:data}

我们在vue组件实例上定义了movieList存放数据,movieIds存放第一次返回时movieIds字段的数据,total数据总数。

// 接上文的省略的代码部分
// 暂时忽略params参数,下文有处理详解/**
*  1. 在promise.then的函数中,我们从data数据里取 movieIds, movieList, coming, total字段
*  2.1 我们以movieIds判断是第一次调用api接口(其他字段也可以,这里先偷懒),那么我们赋值需要的数据 movieIds,total,直接返回movieList数据.
*  2.2 如果2.1没有执行,那么肯定是加载更多数据的接口api_2,我们直接返回coming字段
*  3. 从2.1、2.2我们获得了最后的数据Array,判断数据的长度,更新offset偏移量和movieList数据
*  ps: setImgSize是处理图片的函数,不必理会
**/
getMovieInfoList(params).then(data => {const { movieIds, movieList, coming, total } = dataif (movieIds) {this.movieIds = movieIdsthis.total = totalreturn movieList}return coming
}).then(data => {if (data.length) {this.offset += data.lengththis.movieList.push(...setImgSize(data))$state.loaded()} else {$state.complete()}
})
复制代码

3 参数处理

const { offset, limit, total } = this
const isFirst = offset === 0
if (offset && offset > total) return
const movieIds = this.movieIds.slice(offset, offset + limit).join()
const params = { params: { ...this.params, movieIds } }
复制代码

结尾

水到现在终于要结束了,挤一挤好像也没啥干货,关于接口合并,智者见智,万一以后改接口爆炸了也说不定,作者只是记录下当前遇到类似情况的一种处理方案,或者有更好的方案欢迎大家分享,行文错漏、改善之处欢迎提出来探讨。

Tips: 每天水一篇,生活乐无边。

转载于:https://juejin.im/post/5c80b548518825407b2b64a4

记一次Promise在api接口合并中的实践相关推荐

  1. 搭建股票数据api接口过程中会遇到什么问题?

    搭建股票数据api接口过程中会遇到什么问题?以下这些问题比较常见,对于可能出现问题,建议每个搭建者最好能够提前了解并掌握更好的解决方案,从而应对可能出现的潜在问题. 拉合作方还是推数据? 股票数据ap ...

  2. python实现简单的api接口-python中接口的实现实例

    接口基础知识: 简单说下接口测试,现在常用的2种接口就是http api和rpc协议的接口,今天主要说:http api接口是走http协议通过路径来区分调用的方法,请求报文格式都是key-value ...

  3. api接口加密_谈谈API接口开发中的安全性如何解决

    如今各种API接口层出不穷,一个API的好与不好可以从很多方面来考量,其中"安全性"就是一个API接口最基本也是最重要的一个特点.本文就来跟大家聊聊关于API接口开发的安全性问题. ...

  4. API 接口设计中 Token 类型的分类与设计

    在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...

  5. 网站直达上线运营,API接口开发中

    为什么80%的码农都做不了架构师?>>>    今天(2014-4-14)开通的企业三剑客 的药店直达(http://store.yi18.net) 于是组成了 医药企业的三剑客 医 ...

  6. 超详细讲解大事件项目api接口

    文章目录 1. 初始化 1.1新建项目 1.2 配置 cors 跨域 1.3 配置解析表单数据的中间件 1.4 初始化路由相关的文件夹 1.5 初始化用户路由模块 1.6 抽离用户路由模块中的处理函数 ...

  7. API接口设计 注意问题

    摘要: 总结一下API接口开发过程中的注意事项 1.跨平台性 所谓跨平台是指我们的接口要能够支持不同的终端,比如Android.iOS.windowsphone以及桌面软件.网站等.如:不同的终端每页 ...

  8. 新浪短网址生成java_新浪短链接 推荐几个最新的新浪t.cn短链接生成的API接口

    新浪很久之前提供了长链接转为短链接的公开API,可以把长链接转为t.cn/xxx这种格式的新浪短链接.但是在去年9月的时候,新浪由于政策上的调整,将之前的接口关闭了! 今天就给大家带来几个还可以使用新 ...

  9. 最新智云全能API接口查询PHP源码V1.1

    介绍: 1.[一言/随机语录]2.[必应每日一图]3.[域名是否已注册查询接口]4.[m3u8视频在线解析]5.[随机生成二次元图片]6.[快递查询-支持国内百家快递]7.[二维码图片生成]8.[抖音 ...

最新文章

  1. Spring Cloud构建微服务架构:服务消费(Feign)【Dalston版】
  2. c语言如何监控网卡信息,查看网卡信息及状态和网卡日志信息
  3. 0-MyBatis简介
  4. ZooKeeper之Web管理工具Shepher介绍
  5. WPF的ListBox的数据绑定,但需要添加控件在里面的时候
  6. 报告一下近期读书情况
  7. VB讲课笔记13:二级公共基础
  8. Java动态代理之InvocationHandler最简单的入门教程 1
  9. Java学习日记之 Java-IO流
  10. 区块链底层平台有哪些 区块链底层平台搭建
  11. java integer转成负数_Java 十进制和十六制之间的转化(负数的处理)
  12. cesium实现立体墙(垂直、水平)渐变泛光效果
  13. 人工智能研究的内容:_更深入:人工智能研究的思想史
  14. Siemens Simcenter FloEFD 2021.2.0 for Catia V5
  15. Android 6.0 更新包与已安装应用的签名不一致
  16. 【Android】打包生成APK教程
  17. what Data Fabric
  18. Ubutntu下使用realsense d435i(三):使用yolo v5测量目标物中心点三维坐标
  19. 含论文+辩论PPT+源码等]微信小程序ssm社区心理健康服务平台+后台管理系统
  20. 风丘科技为您提供10M以太网解决方案

热门文章

  1. 推特的id生成器的使用
  2. 如何使用Globus从NCAR官网上下载JRA55数据
  3. iPhone 5S及iWatch或将采用指纹验证技术
  4. Python实现照片卡通化,一拳打破次元壁 | 机器学习
  5. matlab 线性索引 转换,自己编写的 matlab 线性索引转换下标 函数
  6. php 如何输出一张图片,PHP 生成一张图片的两种方法
  7. 从零起步(无需数学和Python基础)编码实现AI框架之第六节课:使用Matrix编写AI框架实战及测试
  8. java jdbcrdd_鸡肋的JdbcRDD
  9. windows电脑离线安装mysql 8_windows环境下手动安装Mysql8
  10. poj2236 Wireless Network