0

0

JS中使用接口步骤详解

php中世界最好的语言

php中世界最好的语言

发布时间:2018-05-24 13:38:10

|

8425人浏览过

|

来源于php中文网

原创

这次给大家带来js中使用接口步骤详解,js中使用接口的注意事项有哪些,下面就是实战案例,一起来看一下。

这篇是 js-interface 的 README,虽然并不是很复杂的一个东西,如果有人看的话我就写写源码思路了 ORZ

介绍

在做一个前后分离的项目时,有些头疼 Api 之类的东西要怎么管理,在阅读 《JavaScript 设计模式》 一书时,第二章提到了在 JavaScript 中模拟接口 (interface) 的概念,以方便使用众多设计模式,因此尝试着做一个接口的模拟。由于我本职是一名后端 Java 开发,因此希望在这个模拟层可以加入 接口默认实现接口继承方法重载 等能力,虽然这些东西加上之后不可避免得会在性能上有所牺牲,但对我来说可以提升一些开发体验(我知道 TypeScript,只是想搞个轮子试试 :P)。

使用

既然初衷是为了方便管理 Api,那么就做一个关于 Api 的 demo。

创建一个接口

const config = {
    // 接口的名字
    name: 'IApi', 
    // 是否打开此接口的 debug 开关
    // 开发时必须打开,否则不会启动 (方法声明、方法实现等)入参的类型检查。
    // 打开这个的情况下,还会获得一些调试用的信息。
    debug: true,          
}
let IApi = new Interface(config)

声明方法

最简单的声明方式:

IApi.method({name: 'getName'})
// 等价于
IApi.method({name: 'getName', args: undefined})

这样就声明了 IApi 接口含有一个 getName 方法,它没有任何参数,也没有默认实现,这就要求在后面任何 IApi 的子接口或实现类必须实现该方法,否则会抛出一个异常。


如果想指定方法的参数列表:

IApi.method({ name: 'getName', args: null })

注意!

argsnull 时表示该方法可以接受任意数量的任意参数,如果重载了一个方法(详细的请参阅后面关于重载的说明):

// 声明一个空参方法
IApi.method({ id: 0, name: 'getName', args: null })
// 重载上面的方法,使其有且只有一个 'string' 类型,名为 name 的参数
IApi.method({ id: 1, name: 'getName', args: [
    {name: 'name', type: 'string', support: val => typeof val === 'string'}
] })

注意!

在参数描述中,type 属性只是一个字符串值,它并不真的代表参数的实际类型。它跟 name 属性一样只是提供用于调试的信息,因此你可以填入任何你认为合适的、足以标记该参数一些信息的字符串值。

真正决定方法是否接受该参数的是 support 属性,当它返回 true 时会检查下一个参数直到所有参数检查完毕或某个位置的参数不被接受。

如果需要,可以在 support 中对实际入参进行特殊处理,比如转换对象、特定属性检查等等。


如果想为方法提供默认实现:

IApi.method({ 
    name: 'getName', 
    // 默认实现,不能为箭头函数!
    implement: function() {
        return "IApi"   
    }
})

回到我们的 demo,综合运用一下:

// 声明两个方法,它们都没有参数,也不需要重载因此这样就可以了
IApi
  .method({ name: 'getName'  })
  // 项目中使用 Axios,因此这里需要一个方法来获取 axios 实例
  .method({ name: 'getAxios' })
// 声明四个请求方式对应的方法
const methods = ['get', 'post', 'put', 'delete']
methods.forEach(method => {
  IApi.method({
    name: method,
    args: null,
    implement: function() {
      // 处理了 this 指向问题,放心用吧
      return this.getAxios()[method].apply(this, arguments)
        .then(responseHandler)
        .catch(errorHandler)
    }
  })
})

继承接口

假定我们要创建接口 A,要继承 B、C、D、E 等接口,使用如下语句:

const A = new Interface({
    name: 'A',
    debug: true
}).extends([B, C, D, E])

extends 方法会将传入的接口所持有的所有方法声明(即通过 Interface.method(config) 所声明的那些方法 )拷贝至接口 A,包括那些方法声明的默认实现。

注意!

一般来说,不会在多个接口中重载同一个方法签名,但如果真的有这样的需求,可以自行设置 id 的规则,比如:

const B = new Interface(...)
  .method({ id: 'B00', name: 'getName', args = [...] })
  .method({ id: 'B01', name: 'getName', args = [...] })
                
const C = new Interface(...)
  .method({ id: 'C00', name: 'getName', args = [...] })

然后实现该方法时指定要实现哪一个声明:

// 注意!如果一个方法被重载,则不能在 class 中声明该方法。
class AImpl { ... } 
const AInstance = new AImpl(...)
B.implement({
    object: AInstance,
    id: 'B00', // 指定要实现的方法声明
    name: 'getName'
})

再次回到我们的 demo,综合运用一下:

const IAuthenticationApi = new Interface({
  name: 'IAuthentication',
  debug: true
})
   // 指明 IAuthenticationApi 继承自 IApi 接口
   .extends(IApi)
IAuthenticationApi
  // 重载方法 login
  // loin (username :string, password :string)
  .method({
    id: 0,
    name: 'login',
    args: [
      {name: 'username', type: 'string', support: val => typeof val === 'string'},
      {name: 'password', type: 'string', support: val => typeof val === 'string'}
    ]
  })
  // login()
  .method({
    id: 1,
    name: 'login'
  })

实现接口

// 编写一个实现类
class AuthenticationApi {
  constructor(axios) { this.axios = axios }
  // 直接实现 getName 方法  
  getName() { return "AuthenticationApi" }
  // 直接实现 getAxios 方法
  getAxios() { return this.axios }
}
// 实现重载方法
IAuthenticationApi
  .implement({
    // 指定挂载实现到 AuthenticationApi 上
    object: AuthenticationApi,
    // 指定此实现是对应 id 为 0 的方法声明
    id: 0,
    name: 'login',
    implement: function(username, password) {
      console.log('带参数的 login')
      // 还记得我们在 IApi 接口中定义了 get 方法(包括默认实现)吗?
      this.get('https://www.baidu.com')
      return Promise.resolve('hello')
    }
  })
  .implement({
    object: AuthenticationApi,
    id: 1,
    name: 'login',
    implement: function () {
      console.log('无参数的 login')
    },
  })
IAuthenticationApi.ensureImplements(AuthenticationApi)

使用接口实现类

    let authenticationService = new AuthenticationApi(axios)
    // 挂载代理函数到实例上,否则会提示
    // Uncaught TypeError: authenticationService.login is not a function
    IAuthenticationApi.ensureImplements(authenticationService)
    authenticationService
        .login('sitdownload', '1498696873')
        // login(string, string) 会返回一个 Promise 还记得吗 :P
        .then(str => alert(`${str} world!`))
    authenticationService.login()

关于日志

首先确保在创建接口时打开了 debug 开关({ debug: true })。

上面的 demo 运行正常的话你将会得到下面的日志:

// 注册方法
Interface 注册方法: IApi.getName()
Interface 注册方法: IApi.getAxios()
Interface 注册方法: IApi.get(any)
Interface 注册方法: IApi.post(any)
Interface 注册方法: IApi.put(any)
Interface 注册方法: IApi.delete(any)
Interface 注册方法: IAuthentication extends IApi.getName()
Interface 注册方法: IAuthentication extends IApi.getAxios()
Interface 注册方法: IAuthentication extends IApi.get(any)
Interface 注册方法: IAuthentication extends IApi.post(any)
Interface 注册方法: IAuthentication extends IApi.put(any)
Interface 注册方法: IAuthentication extends IApi.delete(any)
Interface 注册方法: [0]IAuthentication.login(username :string, password :string)
Interface 注册方法: [1]IAuthentication.login()
// 实现方法
Interface 实现方法: 保存 [0]IAuthentication.login(...) 实现:
ƒ implement(username, password)
Interface 实现方法: 保存 [1]IAuthentication.login(...) 实现:
ƒ implement()
// 匹配方法
Interface 方法匹配: 精准匹配
IAuthentication.login({ username: "sitdownload" } :string, { password: "1498696873" } :string).
// 在控制台这行是可以打开实现的具体位置的
ƒ implement(username, password)
// 方法输出
AuthenticationApi.js?7b55:25 带参数的 login
// 匹配方法
Interface 方法匹配: 无法精准匹配 IAuthentication.get("https://www.baidu.com"),使用 any 实现匹配:
ƒ implement()
Interface 方法匹配: 精准匹配 IAuthentication.login().
ƒ implement()
// 方法输出
AuthenticationApi.js?7b55:35 无参数的 login
// AuthenticationApi.login(username, password) 中请求了 'https://www.baidu.com'
Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1' is therefore not allowed access.
// IApi.get(any) 中将异常直接向下抛了
Uncaught (in promise) {type: "network", payload: Error: Network Error
    at createError (webpack-internal:///./node_modules/_axios@0.18.0@axios/lib/…}

后续

如果要发版了,确认所有的接口方法都正确实现后,就可以把 debug 关掉,这样就不会有 Interface 内部的一些入参检查和调试输出。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

前端面试真题解析

aspx1财付通支付接口源码
aspx1财付通支付接口源码

本支付接口的特点,主要是用xml文件来记录订单详情和支付详情。代码比较简单,只要将里面的商户号、商户key换成你自己的,将回调url换成你的网站,就可以使用了。通过这个实例也可以很好的了解一般在线支付接口的基本工作原理。其中的pay.config文件记录的是支付详情,order.config是订单详情

下载

React结合TypeScript和Mobx步骤详解

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号