Помните практику Promise в слиянии интерфейсов API

JavaScript Promise

слова, написанные впереди

  1. После того, как эта гидрология была опубликована, некоторые друзья сообщили, что написание было слишком плохим, и это действительно была ошибка автора.Уровень кодирования в настоящее время настолько высок, что я могу только огорчить всех, читая этот остроглазый текст, и написание может только улучшаться медленно.
  2. Есть также друзья, которые сообщили, что они запутались.Если вы хорошо обдумаете, это также вина автора.Если вы не ясно выражаете это, пожалуйста, измените его и отправьте его повторно.
  3. Уточните, пожалуйста, что эта статья не имеет ничего общего с Promise.all. Извините, если вы не так поняли.
  4. Некоторые друзья надеются, что краткий обзор может содержать сводку, и не хотят смотреть на код. Позвольте мне объяснить здесь. На самом деле, резюме включено в объяснение интерфейса слияния ниже. Дело, которое будет решено в этой статье, относительно невелико. Бессмысленно говорить о резюме без сценария. Не глядя на бизнес сценарий и код, эта статья действительно не имеет никакой ценности, она предназначена в основном для того, чтобы зафиксировать идею развития бизнеса.

Что касается слияния интерфейсов (я не знаю, есть ли специальный термин, давайте назовем это так), позвольте мне объяснить здесь, что эта статья относится к тому, что данные загрузки инициализации страницы - это API-интерфейс, а тот, который загружает больше данных это другой интерфейс апи, предыдущий интерфейс.Он обязательно будет вызываться.Второй интерфейс может и не вызываться(срабатывает пользователь),но мы инкапсулируем два вызывающих интерфейса и разделяем бизнес-логику.Автор ленив и делает не хочется писать бизнес-логику для двух интерфейсов соответственно.

Введение

В последний раз, когда автор столкнулся с багом post preflight request в своем личном проекте, он написал небольшую статью "Запомнить предварительный запрос данных междоменного пост-запроса», в этой статье только записано, как извлечь бизнес-логику в конкретном проекте, инкапсулировать идею двух API-интерфейсов, разделяющих кусок бизнес-логики, и вдохновить читателей и друзей, то это лучшее, если у вас есть какие-либо вопросы или ошибки , приветствую Всех предлагаю поделиться, и право автора на написание этой статьи должно быть ориентиром.

оОбъединение интерфейсов, У автора также есть описание в документе разработки проекта, вы можете перейти, чтобы увидеть, если вам интересно.

2. Анализ интерфейса Maoyan API

Говорить о кодировании не по делу — хулиганство. Ниже приводится краткое введение в интерфейс Maoyan. Среди них мы обнаружили, что слияние интерфейсов можно использовать на двух страницах Maoyan. Теперь возьмем в качестве примера два API страницы горячего просмотра Maoyan.

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 Все идентификаторы фильмов, общее количество равно общему, и вы должны полагаться на них при запросе большего количества фильмов в будущем.
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 Описание

Информация иллюстрировать
Функция Получить горячий список фильмов
URL //m.maoyan.com/ajax/moreComingList
Формат JSON
HTTP METHOD GET

2.2 Параметры запроса

параметр Типы требуется иллюстрировать Льези
token String false Учетные данные после входа
movieIds String true Запрошенный идентификатор фильма, в зависимости от интерфейса интерфейса инициализации, возвращает поле 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 Maoyan разработан таким образом. Интерфейс API_1 возвращает часть списка фильмов, все идентификаторы фильмов и общее количество фильмов. Только запрос интерфейса API_2 должен передать идентификатор фильма. Параметры запроса интерфейса API, разработанные другими компаниями, могут быть смещены и ограничены.

3. Схема

Чтобы объединить интерфейсы, вы должны решить две проблемы, оценивать интерфейсы и данные обработки

1 оценочный интерфейс

Когда интерфейс api_2 запрашивает данные, вы должны знать идентификаторы фильмов, которые запрашиваются, затем мы должны определить смещение локально как смещение данных.Авторский проект написан vue, и он размещен на экземпляре компонента вью. . Мы устанавливаем смещение равным 0, и смещение должно быть равно 0 при выполнении первого запроса, и мы используем значение смещения в качестве основы для оценки интерфейса.

Код непосредственно ниже

/***
*  业务逻辑部分
*  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_URL

const defaultConfig = {
  baseURL
}

const STATUS_CODE = 200

const 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

Пожалуйста, игнорируйте уродливую инкапсуляцию авторской функции запроса без обработки ошибок (escape

2 Обработка данных

Как видно из вышеприведенного, наша последняя функция вызова API фактически возвращает Promise{:data}

Мы определяем movieList в экземпляре компонента vue для хранения данных, movieIds для хранения данных поля movieIds, когда оно возвращается в первый раз, и общее количество общих данных.

// 接上文的省略的代码部分
// 暂时忽略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 } = data
  if (movieIds) {
    this.movieIds = movieIds
    this.total = total
    return movieList
  }
  return coming
}).then(data => {
  if (data.length) {
    this.offset += data.length
    this.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 } }

конец

Вода наконец-то сейчас кончается.Вроде ничего не поделаешь если ее сжать.По поводу слияния интерфейсов мудрые видят мудрость.Если интерфейс менять в будущем то может взорваться.Автор только что записал решение текущей аналогичной ситуации. , или есть лучшее решение, пожалуйста, поделитесь, ошибки и упущения в письменной форме, и улучшения приветствуются для обсуждения.

Советы: Одна статья воды каждый день, жизнь безгранична.