
在电子商务网站中,用户可以通过鼠标或手势交互实现 360 度全方位查看产品,提升用户体验。现在需要你设计一个
Pipeline管道函数,用于控制 360 度展示产品的动画序列,通过管道连接各个动画步骤,使产品以流畅的方式呈现给用户。
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── css
├── effect.gif
├── js
│ ├── index.js
│ └── utils.js
└── index.html其中:
css 是样式文件夹。index.html 是主页面。js/index.js 是动画序列代码的 js 文件。js/utils.js 是待补充代码的 js 文件。effect.gif 是页面最终的效果图。在浏览器中预览 index.html 页面效果如下:

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

封装一个支持异步的 pipeline 管道函数,能够按顺序执行一系列异步操作,每个异步操作的结果将作为下一个异步操作的输入。
函数参数说明:
initialValue:管道的初始值(即 sequence 中第一个函数的参数)。它是整个异步管道的起点。第一个异步步骤将以此值开始,并且后续步骤将在前一步骤的输出基础上进行。sequence:是一个由具有返回值和可以传参的函数组成的数组,函数可以是普通函数也可以是 Promise 函数。每个函数接收前一个步骤的输出(即该函数的参数是上一个函数的执行结果),并返回一个 Promise。这个数组定义了整个管道中的处理步骤和它们的顺序。函数返回值说明:
pipeline 函数返回一个 Promise,这个 Promise 最终解析为整个管道执行完成后的结果。测试用例如下:
请注意以下用例仅供参考,实际判题时会修改测试用例,请保证代码的通用性。
sequence 中都为普通函数function fn1(data){
return data +'2.开始左转'
}
function fn2(data){
return data+'3.开始右转'
}
pipeline('1.动画开始',[fn1, fn2]).then(res => {
console.log(res)
})
// 打印结果为:'1.动画开始2.开始左转3.开始右转'sequence 中都为 promise 函数function fn1(data){
return new Promise(resolve => {
resolve(data+'->执行第一个动画')
})
}
function fn2(data){
return new Promise(resolve => {
resolve(data+'->执行第二个动画')
})
}
pipeline('动画开始',[fn1, fn2]).then(res => {
console.log(res)
})
// 打印结果为:'动画开始->执行第一个动画->执行第二个动画' 完成后,点击屏幕触发动画序列,最终效果可参考文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。
js/utils.js 文件外的任何内容。pipeline 函数功能进行检测,请保证函数的通用性,不能仅对测试数据有效。sequence 参数都为普通函数且满足需求正确输出,得 5 分。sequence 参数都为 promise 函数且满足需求正确输出,得 5 分。//utils.js
/**
* @param {*} initialValue 初始值
* @param {Array} sequence 由普通函数或 Promise 函数组成的数组
* @return {Promise}
*/
const pipeline = (initialValue, sequence) => {
// TODO: 待补充代码
let promise = Promise.resolve(initialValue);
for(let func of sequence){
promise = promise.then(result=>{
return func(result);
})
}
return promise;
};
// 检测需要,请勿删除
try {
module.exports = { pipeline };
} catch { }<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品360度展示</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<h1>产品展示</h1>
<p class="tip">点击屏幕,360度产品展示</p>
<div class="computer">
<div class="inner">
<div class="screen">
<div class="face-one">
<div class="camera"></div>
<div class="display">
<div class="shade">
<div class="computer-screen">
<div class="loading-bar"></div>
<div class="loading-text">正在启动...</div>
</div>
</div>
</div>
<span>蓝桥云课</span>
</div>
<title>Layer 1</title>
</div>
<div class="computerbody">
<div class="face-one">
<div class="touchpad">
</div>
<div class="keyboard">
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key space"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
<div class="key f"></div>
</div>
</div>
<div class="pad one"></div>
<div class="pad two"></div>
<div class="pad three"></div>
<div class="pad four"></div>
</div>
</div>
<div class="shadow"></div>
</div>
<script src="./js/utils.js"></script>
<script src="./js/index.js"></script>
</body>
</html>1. 头部信息:
<!DOCTYPE html>:声明文档类型为 HTML5。<meta charset="UTF-8">:设置字符编码为 UTF - 8。<meta name="viewport" content="width=device-width, initial-scale=1.0">:使页面在不同设备上正确显示,宽度适应设备宽度,初始缩放比例为 1。<title>产品360度展示</title>:设置页面标题。<link rel="stylesheet" href="./css/style.css">:引入外部 CSS 文件。2. 主体内容:
<h1>产品展示</h1>:显示页面主标题。<p class="tip">点击屏幕,360度产品展示</p>:显示提示信息,告知用户点击屏幕触发展示。<div class="computer">:电脑模型的容器,包含屏幕、机身等部分。 <div class="inner">:内部容器,用于 3D 变换。 <div class="screen">:电脑屏幕部分,包含摄像头、显示屏等。 <div class="computer-screen">:电脑屏幕内部区域,包含加载条和加载文字。<div class="computerbody">:电脑机身部分,包含触摸板、键盘等。<div class="shadow">:电脑的阴影效果。3. 脚本引入:
<script src="./js/utils.js"></script> 和 <script src="./js/index.js"></script>:引入外部 JavaScript 文件。.tip{
position: fixed;
bottom: 5px;
left: 0;
font-size: 16px;
width: 100%;
text-align: center;
}
.computer {
width: 150px;
height: 96px;
position: absolute;
left: 50%;
top: 40%;
transform: translate(-50%, -50%) scale(2);
perspective: 500px;
}
/* 其他样式规则 */1. 提示信息样式:
.tip:提示信息的样式,固定在屏幕底部中央,字体大小为 16px。2. 电脑模型样式:
.computer:电脑模型的容器样式,设置宽度、高度、位置、缩放比例和透视效果。.shadow:电脑阴影的样式,设置位置、大小和阴影效果。.screen 和 .computerbody:分别设置电脑屏幕和机身的样式,包括背景、边框、3D 变换等。.loading-bar 和 .loading-text:加载条和加载文字的样式,使用动画实现加载效果。@keyframes 动画,如 loading 实现加载条的增长,fade - in 实现加载文字的淡入效果,hide - loading - bar 实现加载条的隐藏动画。/**
* @param {*} initialValue 初始值
* @param {Array} sequence 由普通函数或 Promise 函数组成的数组
* @return {Promise}
*/
const pipeline = (initialValue, sequence) => {
let promise = Promise.resolve(initialValue);
for(let func of sequence){
promise = promise.then(result=>{
return func(result);
})
}
return promise;
};
// 检测需要,请勿删除
try {
module.exports = { pipeline };
} catch { }1. pipeline 函数:
initialValue 为初始值,sequence 是一个由普通函数或 Promise 函数组成的数组。Promise.resolve(initialValue) 将初始值包装成一个已解决的 Promise。for...of 循环遍历 sequence 数组,使用 then 方法将每个函数依次应用到前一个 Promise 的结果上,确保函数按顺序执行。2. 模块导出:
try { module.exports = { pipeline }; } catch { }:尝试将 pipeline 函数导出为一个模块,可能用于测试或其他模块引用。四、工作流程▶️ 1. 页面加载:
pipeline 函数。2. 用户交互(点击屏幕):
js/index.js 文件中会监听点击事件。pipeline 函数按顺序执行这些操作。3. 异步操作执行:
pipeline 函数按顺序执行。每个异步操作的结果会作为下一个异步操作的输入,最终完成整个展示流程。