博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS中的洋葱模型
阅读量:6759 次
发布时间:2019-06-26

本文共 1934 字,大约阅读时间需要 6 分钟。

洋葱模型是一种很经典的程序设计思路:

function compose (middleware) {  // some code}复制代码

它能接受一个函数数组,然后返回一个新的函数,达到这样的效果:

let middleware = []middleware.push((next) => {	console.log(0)	next()	console.log(3)})middleware.push((next) => {	console.log(1)	next()	console.log(1.1)})middleware.push(() => {    console.log(2)})let fn = compose(middleware)fn()/*0121.13*/复制代码

当我们尝试执行fn的时候,它会按照顺序调用之前函数数组中的函数,并且给每一个小函数传递一个参数: next函数。

如果在小函数中执行next,就会调用这个函数的下一个函数,如果没有执行next,程序就不会往下走。所以你可以看到上面的打印顺序。

但是问题来了,我们怎么写这个compose函数?

首先, 这个compose函数肯定会返回一个大的函数嘛,所以:

function compose (middleware) {  return function () {  }}复制代码

然后返回的函数是fn,如果我们尝试执行fn, fn将会尝试执行middleware[0],同时就想我们之前说的,它会给这个小函数传入一个next函数

function compose (middleware) {  return function () {    let f1 = middleware[0]    f1(function next(){    })  }}复制代码

然后这个next函数有开关的功能,如果我们执行next函数,next函数就会调用数组中下一个函数,所以

function compose (middleware) {  return function () {    let f1 = middleware[0]    f1(function next(){      let f2 = middleware[1]      f2(function next(){        ...      })    })  }}复制代码

然后。。。这是递归!为了让上面的更优雅,我们可以这样写

function compose (middleware) {   return function () {      dispatch(0)      function dispatch (i) {         const fn = middleware[i]         if (!fn) return null         fn(function next () {            dispatch(i + 1)         })      }   }}复制代码

通过一个dispatch来优雅的实现递增。

然后我们还希望这个函数支持异步函数:

function compose (middleware) {   return async function () {      await dispatch(0)      function async dispatch (i) {         const fn = middleware[i]         if (!fn) return null         await fn(function next () {            dispatch(i + 1)         })      }   }}复制代码

最后一步,允许用户传递参数

function compose (middleware) {   return async function () {      let args = arguments      await dispatch(0)      function async dispatch (i) {         const fn = middleware[i]         if (!fn) return null         await fn(function next () {            dispatch(i + 1)         }, ...args)      }   }}复制代码

参考:

源代码:

转载地址:http://uxbeo.baihongyu.com/

你可能感兴趣的文章
JAVA中的参数按值传递与按引用传递
查看>>
与Recommender System相关的会议及期刊
查看>>
如何理解ip路由和操作linux的路由表
查看>>
WCF的几种寄宿方式 ( 转)
查看>>
数字数据fzu 2120 数字排列
查看>>
ORACLE 数据库 SQL 转换 只取 年和月
查看>>
区间查询[2009国家集训队]小Z的袜子(hose)
查看>>
Android之使用微信开放api (三)---注册与反注册应用到微信
查看>>
我是怎样看待微博的
查看>>
论《我是如何安慰女友的》
查看>>
nullnull用宏定义swap(x,y)
查看>>
【Javascript】类,封装性 -- 1
查看>>
Mono for Android安装配置破解
查看>>
uploadfy 常见问题收集
查看>>
WPF----数据绑定
查看>>
子类化GetOpenFileName/GetSaveFileName, 以及钩子函数OFNHookProc的使用的简要说明
查看>>
C语言中判断int,long型等变量是否赋值的方法
查看>>
leetcode -- Longest Valid Parentheses
查看>>
详解JAVA输出Hello World
查看>>
概率问题随笔
查看>>