当前位置: 首页 > article >正文

备赛蓝桥杯之第十五届职业院校组省赛第三题:产品360度展示

提示:本篇文章仅仅是作者自己目前在备赛蓝桥杯中,自己学习与刷题的学习笔记,写的不好,欢迎大家批评与建议


由于个别题目代码量与题目量偏大,请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题,在这里只提供部分原题代码

本题目为:2024年十五届省赛职业院校组真题第三题:产品360度展示


题目:

需要考生作答的代码段如下:

/**
 * @param {*} initialValue 初始值
 * @param {Array} sequence 由普通函数或 Promise 函数组成的数组
 * @return {Promise} 
 */


const pipeline = (initialValue, sequence) => {
    // TODO: 待补充代码
    
};

题目要求:

请在 `js/utils.js` 文件中的 TODO 部分,实现以下目标:

封装一个支持异步的 `pipeline` 管道函数,能够按顺序执行一系列异步操作,每个异步操作的结果将作为下一个异步操作的输入。

答案:

const pipeline = (initialValue, sequence) => {
    // TODO: 待补充代码
    return sequence.reduce(async (x, f) => f(await x), initialValue)
};

拓展学习

组合与管道

    reduce方法

    累加器与当前值的类似操作`(x,y)=>y(x),初始值`

前言

我们假设一种需求,即“让一个数字,先进行+1,再进行*3”

通常我们普遍来说会像这样来实现这个效果

// value (1+1)*3 //6

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}

console.log(mul3(add1(1))) //6

这样写,我们可以实现上述操作

但是如果有很多的步骤,那么我们会发现后续调用的方法会非常多非常麻烦

所以我们就引入了一个方法组合(compose)

组合

像上述假设,我们再使用组合的方法来实现

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}

function compose (f,g){
	return function (x){
		return f(g(x))
	}
}

console.log(compose(mul3,add1)(1)) //6

注意compose组合是从右向左去执行,因此在上述定义代码中

compose (f,g)

先去执行函数g再去执行函数f,即f(g(x))

在运用代码中

compose(mul3,add1)

先去执行add1再去执行mul3

当产生更多的操作时,我们可以使用递归迭代的方法来定义compose

递归

当有[funs[0],funs[1],funs[3]]时

将funs[3]输出结果传递给funs[1]再将结果传递给funs[0]

定义代码如下

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}
function compose(...funs){
	let count = funs.length -1;
	let result = undefined;
	
	return function fn(x){
		if(count < 0){
			return result;
		}
		result = funs[count--](x)
		return fn(result)
	}
}
console.log(compose(mul3,add1)(1)) //6

迭代

当有[funs[0],funs[1],funs[3]]时

相比递归来说,迭代的方法,就是把funs[3]->funs[1]->funs[0]三个方法,初步灌进去

定义代码如下

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}
function compose(...funs){
	let callback = function(f,g){
		return function(x){
			return f(g(x))
		}
	}
	
	let fn = function(funs[2](x)){
		return funs[0]funs[1](fun[2](x))
	}
	
	for(let i=1;i < funs.length; i++){
		fn = callback(fn, funs[i])
	}
	
	return fn;

}

console.log(compose(mul3, add1)(1)) //6

reduce的实现

reduce的实现就是累加器的功能

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}
function compose(...funs){

	if(funs.length === 0){
		return arg => arg
	}
	
	if(funs.length ===1){ }
	
	return funs.reduce((a,b) => (...args) => a(b(...args)))
}

console.log(compose(mul3, add1)(1)) //6

管道

管道相比组合来说唯一的区别其实就是

组合:从右向左

管道:从左向右

而对于定义代码来说,

就是加上reverse()即可

function add1(x){
	return x + 1;
}
function mul3(x){
	return x * 3;
}
function pipe(...funs){

	if(funs.length === 0){
		return arg => arg
	}
	
	if(funs.length ===1){ }
	
	return funs.reverse().reduce((a,b) => (...args) => a(b(...args)))
}

//这就变成了'先*3再+1'
console.log(pipe(mul3, add1)(1)) //4

本题作者想说

目标

    Pipeline 管道函数

    处理一系列的异步操作,并且在处理时,需要按顺序执行,每个任务的结果会作为下一个任务的输入。

思路

观察代码

    观察需要修改的代码

    在题目中也有相对官方的解释

- `initialValue`:管道的初始值(即 `sequence` 中第一个函数的参数)。它是整个异步管道的起点。第一个异步步骤将以此值开始,并且后续步骤将在前一步骤的输出基础上进行。

- `sequence`:是一个由具有返回值和可以传参的函数组成的数组,函数可以是普通函数也可以是 Promise 函数。每个函数接收前一个步骤的输出(即该函数的参数是上一个函数的执行结果),并返回一个 Promise。这个数组定义了整个管道中的处理步骤和它们的顺序。

- `pipeline` 函数返回一个 `Promise`,这个 `Promise` 最终解析为整个管道执行完成后的结果。

    我们自己理解起来呢,即

    sequence就是让产品动起来的函数,由于动起来的情况与函数太多,所以sequence就是一个函数数组

    initialValue就是整个sequence函数数组的初始值,即初始的产品状态

     /**

     * @param {*} initialValue 初始值

     * @param {Array} sequence 由普通函数或 Promise 函数组成的数组

     * @return {Promise}

     */

    const pipeline = (initialValue, sequence) => {

        // TODO: 待补充代码

    };

    经过我们的console.log分析,发现

    initialValue的值为:

    <div class="inner" style="transition: unset; transform: rotateX(-20deg) rotateY(0deg) rotateZ(0deg); background-position: right center;">

        <div class="screen" style="transition: unset; transform: rotateX(0deg);">…</div>

        <div class="computerbody">…</div>

    </div>

    sequence的值为:

    (5) [ƒ, ƒ, ƒ, ƒ, ƒ]

        0: (element) => {…}

        1: (element) => {…}

        2: (element) => {…}

        3: (element) => {…}

        4: (element) => {…}

        length: 5

    [[Prototype]]: Array(0)

    这样我们就可以清晰的理解,sequence中的函数来控制initialValue某些具体的值从而实现360度的展示

    其次,观察具体的值之后,我们还看到了`const pipeline = (initialValue, sequence) =>`

    这就表示我们要最具体的使用pipeline管道函数来处理这个事件

分析逻辑

    Pipeline 管道函数:Pipeline 管道函数是一种用于数据处理和转换的编程模式,它将一系列的处理步骤串联起来,使得数据可以在这些步骤之间流动和转换。

    我们首先知道了具体的函数操作,那么我们就要使其每个函数都被执行,可以理解为将数组中的每个函数都遍历一遍

    这样我们就用到了reduce方法:reduce方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

    将每个sequence中的方法进行遍历

sequence.reduce()

    内部的处理,首先我们要定义两个值

    一个为累加器,将当前被执行的函数进行保存与执行:x

    一个当前的值(当前执行的方法),说明当前正在用的是sequence中的哪个方法:f

    (x, f) =>

    之后我们将当前的x作为函数去执行当前的方法f,

    在后面会说明,因为每次调用之后,都会有一个函数,重新初始化这个x值,因此传入x值无关紧要

    f(x)

    之后定义异步函数,因为该操作一定要是异步的,即当await后的函数执行过后,再次执行async的函数

    这里就是当x传入之后再执行下一次sequence中的函数,即:

    async (x, f) => f(await x)

    最后题目要求中提到`第一个异步步骤将以此值开始,并且后续步骤将在前一步骤的输出基础上进行。`

    说明每一个方法的执行都要使initialValue作为初始值,因此再次定义一个初始值,即:

    , initialValue

    最后将代码返回出去即可

    return
设计代码
    return sequence.reduce(async (x, f) => f(await x), initialValue)

注意

    Pipeline 管道函数

    reduce方法

    累加器与当前值的类似操作`(x,y)=>y(x),初始值`


感谢观看此篇文章,谢谢大家的支持,本片文章只是我自己学习的历程,有些写的不好地方欢迎大家交流改动。

长路漫漫,我们还需努力!


http://www.kler.cn/a/515912.html

相关文章:

  • 回首2024,展望2025
  • Lsky-Pro在线图片搭建教程(Docker部署方式)
  • 局域网中 Windows 与 Mac 互相远程连接的最佳方案
  • 【组件库】使用Vue2+AntV X6+ElementUI 实现拖拽配置自定义vue节点
  • 2025.1.20——二、buuctf BUU UPLOAD COURSE 1 1 文件上传
  • 什么是HTTP3?
  • Alibaba Spring Cloud 四 Seata 的核心组件:TC
  • 【浙江省乡镇界】面图层shp格式arcgis数据+乡镇名称和编码+wgs84坐标无偏移内容测评
  • 在 Windows 11 中为 SMB 3.x 文件共享协议提供 RDMA 支持
  • 【C++图论 并集查找】2492. 两个城市间路径的最小分数|1679
  • TOGAF之架构标准规范-信息系统架构 | 数据架构
  • 小利特惠源码/生活缴费/电话费/油卡燃气/等充值业务类源码附带承兑系统
  • c语言贪吃蛇(极简版,基本能玩)
  • 【豆包MarsCode蛇年编程大作战】花样贪吃蛇
  • 操作系统(Linux Kernel 0.11Linux Kernel 0.12)解读整理——内核初始化(main init)之缓冲区的管理
  • 百度APP iOS端磁盘优化实践(上)
  • 深入理解Spring Boot:启动方式、注解、配置文件与模板引擎
  • 深度理解递归(树的深度优先遍历、费波那契数列)c++
  • Effective C++ 规则43:学习处理模板化基类内的名称
  • linux+docker+nacos+mysql部署
  • 认识Django项目模版文件——Django学习日志(二)
  • Spring Boot整合Thymeleaf、JDBC Template与MyBatis配置详解
  • 【C语言】编译链接
  • 软考信安26~大数据安全需求分析与安全保护工程
  • 【C++笔记】哈希表底层实现的深度剖析
  • 车间设备数据采集解决方案