/**
* 请实现一个通用的Array解构赋值方法 destructuringArray,
* 可将目标数组(targetArray)通过ES6的解构格式(formater),
* 输出解构结果对象。
* 考察点:
* 字符串、数组、对象处理 / 解构概念 / 数据结构 / 正则
*
* 设计参考(可选提供):
*
* - 通过优化函数名及参数语义以方便考生快速理解题目。
* - 函数名为 destructuringArray(解构数组)功能是将目标数组通过以下解构格式解构为最终对象。
* - 入参1是目标数组:targetArray{array}
* - 入参2是解构格式:formater{string}
* - 输出为 {object},。
*
* Example:
* destructuringArray( [1,[2,3],4], "[a,[b],c]" );
* // result
* { a:1, b:2, c:4 }
*/
/**
* 定义
*/
var
// 先准备好目标数组
targetArray = [1,[2,3],4],
// 再准备好解构格式
formater = "[a,[b],c]",
/**
* 解构数组
* @param targetArray{Array} 目标数组
* @param formater{String} 解构格式
* @return {Object} 结果对象
*/
destructuringArray = function(targetArray,formater){
};
// 运行
console.dir( destructuringArray(targetArray,formater) )
参考答案一:
var
// 先准备好目标数组
targetArray = [1, 5, [2, [3, 7]], 4],
// 再准备好解构格式
formater = "[a,e,[b,[c,f]],d]",
/**
* 解构数组
* @param targetArray{Array} 目标数组
* @param formater{String} 解构格式
* @return {Object} 结果对象
*/
destructuringArray = function(targetArray, formater) {
const helper = {};
const len = formater.length;
let i = -1;
let curVar = '';
let curLayer = -1;
const layer = {};
// 只遍历一次,保证最小时间复杂度: O(n)
while (i++ < len - 1) {
let curCode = formater.charAt(i);
if (curCode === '[') {
curLayer++; // 层级加一级
} else if (curCode === ']') {
if (isNum(layer[curLayer])) {
layer[curLayer]++;
} else {
layer[curLayer] = 0;
}
curVar && (helper[curVar] = getAryItem(targetArray, layer, curLayer));
curVar = '';
curLayer--;
} else if (curCode === ',') { // 当前层级加一
if (isNum(layer[curLayer])) {
layer[curLayer]++;
} else {
layer[curLayer] = 0; // 从0开始
}
curVar && (helper[curVar] = getAryItem(targetArray, layer, curLayer));
curVar = '';
} else {
curVar += curCode;
}
}
return helper;
};
function isNum(arg) {
return typeof(arg) === 'number';
}
function getAryItem(ary, layer, curLayer) {
if (curLayer === 0) {
return ary[layer[curLayer]];
}
let res = ary;
const keys = Object.keys(layer);
keys.forEach((key, index) => {
if (key <= curLayer) {
if (index === keys.length - 1) {
res = res[layer[key]];
} else {
res = res[layer[key] + 1];
}
}
});
return res;
}
// 运行
const res = destructuringArray(targetArray, formater);
console.log('最终的结果:');
console.dir(res);
参考答案二:
var
// 先准备好目标数组
targetArray = [1,[2,3],4],
// 再准备好解构格式
formater = "[a,[b],c]",
/**
* 解构数组
* @param targetArray{Array} 目标数组
* @param formater{String} 解构格式
* @return {Object} 结果对象
*/
destructuringArray = function(targetArray,formater){
var
// 准备结果容器
result = {},
// 创建编制器
formater = eval( formater.replace(/(\w+)/g,"'$1'") )
;
// 创建映射函数
var mapping = function(targetArray,formater){
for(var i=0; i<formater.length; i++){
var formaterItem = formater[i],
targetItem = targetArray[i]
;
// 如果是数组则进行递归
if(Array.isArray(formaterItem)){
mapping(targetItem,formaterItem);
}else if(formaterItem){
result[formaterItem] = targetItem;
}
}
};
// 开始映射
mapping(targetArray,formater);
// 返回对象
return result;
}
;
// 运行
console.dir( destructuringArray(targetArray,formater) )
/**------- 编码题目一 --------- **/
/**
* 说明:生成一个指定长度(默认6位)的随机字符,随机字符包含字母数字。
* 输入:输入随机字符长度,无输入默认6位
* 输出:随机字符,如"6bij0v"
*/
常规解法:在给定字符空间内取随机组合。
/**
* 生成长度为n的随机索引序列。
* @param {Number} n - 索引长度{1,}
* @param {Number} max - 最大索引值{0,}
* @param {Boolean} repeat - 是否允许重复
*/
function genRandomIndex(n = 1, max = 0, repeat = true) {
let res = [],
regExN = /\d+/;
// 若n非数值或<1, 返回空Array
if (!regExN.test(n) || n < 1) {
return [];
}
// 若max非数值或<0, 返回空Array
if (!regExN.test(max) || max < 0) {
return [];
}
n = Math.floor(n);
max = Math.floor(max);
repeat = !repeat ? 0 : 1;
let maxN = max + 1;
if (!repeat && n > maxN) {
throw Error('At non-repeated mode n must lte max + 1');
}
let genRndInx = (maxN) => {
return Math.floor(Math.random() * maxN);
};
while (res.length < n) {
let rndInx = genRndInx(maxN);
if (!repeat) {
while (res.includes(rndInx)) {
rndInx = genRndInx(maxN);
}
}
res.push(rndInx);
}
return res;
}
/**
* 生成由字母及数字组成,长度为n的随机字符串。
* @param {Number} n - default 6
* @param {Boolean} repeat - 是否允许重复
*/
function randomstr(n = 6, repeat = true) {
let rndInx = genRandomIndex(n, 61, repeat); // 0-9A-Za-z
let res = rndInx.map((val, inx, ary) => {
if(val <= 9){
return val;
}
if(val >= 10 & val <= 35){
return String.fromCharCode(val + 55);
}
if(val >= 36 & val <= 61){
return String.fromCharCode(val + 61);
}
});
return res.join('');
}
36进制转换解法,此解法有限制,无法区分字母大小写,无法处理是否重复的问题
/**
* 生成由字母及数字组成,长度为n的随机字符串。
* @param {Number} n - default 6
*/
function randomstr(n = 6) {
let res = '';
// 若n非数值或<=0, 返回空串
if (!/\d+/.test(n) || n <= 0) {
return '';
}
// 若n非整数,向下取整
n = Math.floor(n);
let max = Number.MAX_SAFE_INTEGER,
log36max = Math.floor(Math.log(max) / Math.log(36)), // 计算以36为底,max的对数,即单次可生成的最大随机串长度
min = parseInt('9'.repeat(log36max - 1), 36), // 确保单次生成长度为log36max
roundn = Math.ceil(n / log36max); // 根据n判断需要生成多少轮
for (let i = 0; i < roundn; i++) {
res += Math.floor(Math.random() * max - min).toString(36);
}
return res.substr(0, n);
}
/**
* 生成由字母及数字组成,长度为n的随机字符串。
* @param {Number} n - default 6
*/
function randomstr(n = 6) {
let res = '';
// 若n非数值或<=0, 返回空串
if (!/\d+/.test(n) || n <= 0) {
return '';
}
// 若n非整数,向下取整
n = Math.floor(n);
while (res.length < n) {
res += Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36);
}
return res.substr(0, n);
}
题目三
var longTapBtn = document.getElementById('long-tap'),
longTapTimeout, longTap = function(target) {
var eventName = 'longTap'; // 得分点: 封装成自定义事件
try {
var event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, false, true);
} catch (e) {
var event = document.createEvent("Event");
event.initEvent(eventName, false, true);
}
target.dispatchEvent(event);
}; // 得分点: 针对于全局定义
window.addEventListener('touchstart', function(e) {
longTapTimeout = setTimeout(function() {
longTap(e.target);
}, 1000);
});
window.addEventListener('touchend', function(e) {
clearTimeout(longTapTimeout);
}); // 得分点: 判断移动
window.addEventListener('touchmove', function(e) {
clearTimeout(longTapTimeout);
});
longTapBtn.addEventListener('longTap', function(e) {
console.log('longTap');
});
//e.g
var FuncA = function(){};
throttle(A,200); //让A 200ms不被调用后才执行一次;
// method为传入方法,delay为延迟时间;
注:返回一个函数 function throttle(method,delay){}
阅卷参考:参考答案:
var throttle = function(fn, delay) {
var timer = null;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
}
知识域: 移动 难度系数: B 解析: 本题主要考察对移动开发中常见问题:函数节流的理解;
function add(num1, num2) {
return this.value + num1 + num2;
}
var data = {
value: 1
};
var addEx = add.bindX(data, 2);
addEx(3); // 6
阅卷参考:答案:
Function.prototype.bindX = function(that) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return self.apply(that, args.concat(Array.prototype.slice.call(arguments)))
}
};
知识域:javscript 难度系统数:C 解析:考查对javscript函数调用的理解
阅卷参考:// 参考答案
function getLongestParenthese(str) {
const len = str.length;
const stack = [];
let answer = 0;
let start = -1;
for (let i = 0; i < len; i++) {
if (str[i] === '(') {
stack.push(i);
} else {
if (stack.length === 0) {
start = i;
} else {
stack.pop();
if (stack.length === 0) {
answer = Math.max(answer, i - start);
} else {
answer = Math.max(answer, i - stack[stack.length - 1]);
}
}
}
}
return answer;
}
阅卷参考:解析: 主要考察对于大型JavaScript应用程序的开发如何平衡开发效率及可维护性,以及设计DSL需要注意的一些问题 答题思路(仅供参考) 首先需要明白什么是大型JavaScript应用程序? 基于特定的应用架构的,需要持续维护的,UI逻辑展示较为复杂的应用程序 其次再看DSL在其中承担什么作用? DSL在其中主要用来解决在某种应用架构模式下面的痛点来提升开发效率,比如针对本题可以从MVC应用模式的一些问题点出发。 再看设计DSL的一些原则 比如使用起来足够清晰 , 要具有一定的可维护性,可调试性,可扩展性等 按照上面的原则,最后简单表述如何实现一个DSL 比如功能层面使用词法分析和语法分析等, 维护层面给出一定的调试方案等。
export default function() {
return ({ dispatch, getState }) => next => action => {
if (______) {
return ______;
}
return next(action);
};
};
答案: 1 typeof action === 'function'
2 action(dispatch, getState)
难度系统数:B 解析:考查对redux中间件的了解
// 注意:一个replace中有两处填写,其中有一处填写,默认已使用一次replace
// 字符串str
{
msg = "{\"url\":\"MBU0016G7G004SS00081\",\"data\":{\"a\":1,\"b\":[2,3]}}";
}
function string2Json(str) {
str = str.replace(/{\n.+=.\"/, '')
.replace(/\";\n}/g, '')
.replace(/\\/g, '')
return JSON.parse(str)
}
阅卷参考:答案: 1. /{\n.+=."/, ‘’ 2. /";\n}/g, ‘’, 3. /\/g, ‘’ 知识域: JS正则表达式 难度系统数:B 解析: 题干信息较少,但最后JSON.paese()提醒只需将字符串转换为满足JSON的字符串即可
[功能设计] 考查对一具体需求的分析和抽象能力,再展开设计。能否抽象出核心原理,在于运行过程中产生数据的存储,undo/redo指令触发数据应用更新到视图上的过程。
[架构设计] 考查对小型功能库设计的技术分析和技术方案选型过程,通用性扩展性是否思考到位。更佳的能否明确的时序图以及架构图。 - [技术实施] 技术实施上的具体考量,比如是否能描述数据存储的结构设计,使用命令模式或是Immutable(持久化数据结构)等模式设计,是否有流程机制方面的控制等。
[功能缺陷] 能够理性分析出自己在某种思路下的设计缺陷和优点,以及适用的场景,并且可以阐述缺陷与优点的平衡。 难度系统数:A
hover
disabled
Normal:
<button class="ui-button ui-button-primary ui-button-large">primary</button>
<button class="ui-button ui-button-secondary ui-button-large">secondary</button>
<button class="ui-button ui-button-normal ui-button-large">normal</button>
disabled:
<button class="ui-button ui-button-primary ui-button-large disabled">primary</button>
<button class="ui-button ui-button-secondary ui-button-medium disabled">secondary</button>
<button class="ui-button ui-button-normal ui-button-small disabled">normal</button>
Size:
<button class="ui-button ui-button-primary ui-button-large">large</button>
<button class="ui-button ui-button-secondary ui-button-medium">medium</button>
<button class="ui-button ui-button-normal ui-button-small">small</button>
<button class="ui-button ui-button-normal ui-button-mini">mini</button>
<style type="text/css">
/* Bounding */
.ui-button{
border-radius:3px;
border:none;
transition: all .3s ease-out;
outline:none;
}
/* state: normal & hover & disabled */
.ui-button-primary{
background: #FF7519;
color: #FFF;
}
.ui-button-primary:hover{
background: #EB650C;
color: #FFF;
}
.ui-button-secondary{
background: #2196F3;
color: #FFF;
}
.ui-button-secondary:hover{
background: #0F87E6;
color: #FFF;
}
.ui-button-normal{
background: #FFF;
color: #333;
}
.ui-button-normal:hover{
background: #D9DCE0;
color: #333;
}
.ui-button-primary.disabled,
.ui-button-secondary.disabled,
.ui-button-normal.disabled{
background: #CCC;
color: #FFF;
}
/* size */
.ui-button-large{
height: 40px;
padding: 0 20px;
line-height: 40px;
font-size: 18px;
}
.ui-button-medium{
height: 28px;
padding: 0 12px;
line-height: 28px;
font-size: 14px;
}
.ui-button-small{
height: 24px;
padding: 0 12px;
line-height: 22px;
font-size: 12px;
}
.ui-button-mini{
height:14px;
line-height:10px;
font-size: 10px \9;
font-size:10px;
transform: scale(0.7);
}
</style>
@media all and (______) and (______){
/* 横屏样式 */
}
min-width: 321px
max-width: 568px
阅卷参考:解法1:常用布局办法 html代码 解析:考察布局能力(可以采用传统的absolute,也可以使用flex布局),另外考验一下line-gradient灵活应用。
<div class="graph">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
<div class="bar bar4"></div>
<div class="bar bar5"></div>
</div>
<style type="text/css">
.graph {
width: 500px;
height: 400px;
border: 2px solid #000;
border-top: none;
border-right: none;
position: relative
}
.bar {
position: absolute;
bottom: 0;
width: 50px
}
.bar1 {
left: 10px;
height: 30%;
background: #f00
}
.bar2 {
left: 80px;
height: 80%;
background: #ddd
}
.bar3 {
left: 160px;
height: 70%;
background: #0fd
}
.bar4 {
left: 240px;
height: 60%;
background: #ff0
}
.bar5 {
left: 320px;
height: 90%;
background: #234
}
</style>
<!-- 解法2:利用line-gradient实现 html代码 -->
<div class="graph"></div>
<style type="text/css">
.graph {
width: 500px;
height: 400px;
border: 2px solid #000;
border-top: none;
border-right: none;
background: linear-gradient(to top, #f00 30%, transparent 0) 20px 0, linear-gradient(to top, #ddd 80%, transparent 0) 90px 0, linear-gradient(to top, #0fd 70%, transparent 0) 160px 0, linear-gradient(to top, #ff0 60%, transparent 0) 230px 0, linear-gradient(to top, #234 90%, transparent 0) 300px 0;
background-size: 50px 100%;
background-repeat: no-repeat;
}
</style>
var A = document.getElementById('a');
document.addEventListener('click', function(e) { A.style.display = 'none'; }, false)
A.addEventListener('click', function(e) { e.stopPropagation(); })
- 方法2:
```javascript
var hiddenTimeout, A = document.getElementById('a');
document.addEventListener('click', function(e) {
hiddenTimeout = setTimeout(
function() {
A.style.display = 'none';
}, 20)
}, __true__)
A.addEventListener('click', function(e) {
if (hiddenTimeout) {
__clearTimeout(hiddenTimeout)__;
}
})
本题着重考察对于JavaScript的DOM事件执行顺序的理解,核心思路是冒泡的情况下阻止元素冒泡,捕获的情况下使用延时移除隐藏的行为
考核点:
/*
请实现find函数,使下列的代码调用正确。
约定:
title数据类型为String
userId为主键,数据类型为Number
*/
var data = [
{userId: 8, title: 'title1'},
{userId: 11, title: 'other'},
{userId: 15, title: null},
{userId: 19, title: 'title2'}
];
var find = function(origin) {
//请补充你的代码
}
//查找data中,符合条件的数据,并进行排序
var result = find(data).where({
"title": /\d$/
}).orderBy('userId', 'desc');
console.log(result); // [{ userId: 19, title: 'title2'}, { userId: 8, title: 'title1' }];
本题着重考核综合素质以及解决问题的思路。 1. 链式调用 2. 闭包 3. 简单的SQL理解 4. 简单的过滤与排序 5. 简单的正则 参考答案:
var find = function(origin) {
return {
where: function(field, value) {
return where(origin, field, value);
}
}
};
//查询条件
var where = function(origin, field, rule) {
var result = filter(origin, field, rule);
return {
orderBy: function(orderField, direction) {
return orderBy(result, orderField, direction)
}
}
};
//排序, 考虑到可能出现asc的情况加分
var orderBy = function(origin, field, direction) {
return origin.sort(function(left, right) {
var result = left[field] - right[field];
return direction === 'desc' ? -result : result;
});
};
//过滤
var filter = function(origin, field, rule) {
var result = [];
for (var i = 0; i < origin.length; i++) {
var item = origin[i];
var value = item[field];
//需要考虑到value可能为null
if (value && rule.test(value)) {
result.push(item);
}
};
return result;
}
<div>
<input onChange={this.onChange} value={this.state.text} />
</div>
编译成JS是__
阅卷参考:
答案:V,className, React.createElement("div", null, React.createElement("input", {onChange: this.onChange, value: this.state.text}) )
知识域:React 难度系统数:B+ 解析: 考察一些基础概念和编译后结构
class Counter extends React.Component {
select(val) {
console.log('you have select ' + val);
}
render() {
return (<ul>
{
['a','b','c'].map((item, index) => {
return <li onClick={______}>{item}</li>
})
}
</ul>)
}
}
阅卷参考:答案:
[普通答案] this.select.bind(this, item)
[lambda答案] ()=>{this.select(item)}
知识域:React事件, 作用域绑定 难度系数:B 解析:考察React中事件的自动绑定。对于组件本身的事件方法,官方推荐的写法是必须使用bind(this)的形式绑定:this.method.bind(this)}
const yourFunction = function(func, threshold) {
// 请实现
}
const triggerSearch = yourFunction((val) => {
const {
onSearch
} = this.props
onSearch(val)
}, 300)
triggerSearch(searchText)
阅卷参考:参考答案:
// leading, trailing 皆为 true...,可配置更佳
export const throttle = function(func, thresold) {
let called = false,
lastargs = null
return function(...args) {
const context = this lastargs = args
if (!called) {
func.apply(context, args) lastargs = null called = true setTimeout(\_ => {
called = false
if (lastargs) func.apply(context, lastargs)
}, thresold)
}
}
}
事件绑定(同一个key可以绑定多个事件):
EventStore.on({key:'counter/add', fn:function(payload){
// payload是触发时传入的数据
}})
事件触发:
EventStore.trigger({key:'counter/add', payload:{step:5}});
阅卷参考:答案:
var EventStore = {
events: {},
on: function(eventObj) {
/* 监听事件 */
if (!eventObj || !eventObj[key] || !eventObj[fn]) return;
var key = eventObj.key,
fn = eventObj.fn;
if (!this.events[key]) {
this.events[key] = [];
}
this.events[key].push(fn);
},
trigger: function(eventObj) {
/* 触发事件 */
if (!eventObj || !eventObj[key]) return;
var key = eventObj.key,
payload = eventObj.payload || {};
if (this.events[key]) {
for (var i = 0, ln = this.events[key].length; i < ln; i++) {
this.eventskey(payload);
}
} else {
// do nothing...
}
}
};
知识域:React事件, 组件间通信实践 难度系数:B 解析:官方的通信解决Flux的dispatcher基于EventStore实现。考察对于解决组件间通信。
var data = [
{year:2006,data:450},
{year:2001,data:120},
{year:2002,data:160},
{year:2008,data:600},
{year:2005,data:380},
{year:2000,data:100},
{year:2004,data:300},
{year:2009,data:700},
{year:2010,data:810}
]
function insert(data) { // }
insert(data);
<br />阅卷参考:参考解法: <br />知识域:Javascript 难度系统数:B 解析:考察对数据的处理能力
<a name="8215af16"></a>
## 题目二十二: 顺序变换
```javascript
//有一个数组,里面只存在 _ 和 字母,比如 [‘_‘, ‘d’, ‘c’, ‘_‘, ‘e’, ‘_‘, ‘a’, ‘*‘]。现在需要把这个数组中的所有星号移动到左边,所有的字母移动到右边,所有字母的顺序不能改变。
var arr = ['*', 'd', 'c', '*', 'e', '*', 'a', '*'];
function parse(arr){
...
}
console.log(parse(arr));
阅卷参考:解析: - 算法基础 - 发散思维 - 数组的相关用法
//参考解法一:常规思维
function parse(arr) {
var counter = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == '*') {
arr.splice(i, 1);
counter++;
i--;
}
}
while (counter > 0) {
arr.unshift('*');
counter--;
}
return arr;
}
//参考解法二: 发散思维
function parse(arr) {
var str = arr.join(''),
counter = 0;
str = str.replace(/\*/g, function() {
counter++;
return '';
}) while (counter > 0) {
str = '*' + str;
counter--;
}
return str.split('');
}
var A = [1, 2];
var B = "String";
var C = /[\w]/g;
var D = new Date();
var E = new Error("something wrong");
console.log(Common.getType(A)) //array
console.log(Common.getType(B)) //string
console.log(Common.getType(C)) //regexp
console.log(Common.getType(D)) //date
console.log(Common.getType(E)) //error
阅卷参考:解析:该题主要考核对数据类型的理解、底层基础知识以及编码通用性的考虑,实际很简单,但是容易进入误区,特别是如何进行识别数据类型 难度:B+ 领域:Javascript 参考答案
var Common = {
// 定义所有数据类型
_DATATYPES: ["Object", "Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Error", "Null", "Undefined"],
// 数据类型对应MAP
_TYPES: {},
// 数据类型MAP是否初始化
_INITED: false,
getType: function(obj) {
var result;
// 初始化数据类型
if (!this._INITED) {
for (var i = 0; i < this._DATATYPES.length; i++) {
var n = this._DATATYPES[i];
this._TYPES["[object " + n + "]"] = n.toLowerCase();
}
this._INITED = true;
}
// 重点在于({}).toString.call的应用
result = this._TYPES[({}).toString.call(obj)];
return result ? result : typeof obj;
}
};
参数解释:
使用例子:
var a = [1, 2, 3];
var b = a.filter(function(value) {
return value <= 2;
});
// b ==> [1, 2]
阅卷参考:答案:
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun /*, thisArg*/ ) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
5分钟简历筛选用的,本题现实中肯定不会遇到,属于脑筋急转弯类型,考察选手对defineProperty的掌握
// 本代码在浏览器中执行,在此填充代码是下面的打印能够成功执行
//
//
//
if (a === 'animal' && a === 'dog' && a === 'husky') {
console.log('Haha, husky');
}
参考答案
var counter = 0;
Object.defineProperty(window, 'a', {
get: function () {
return ['animal', 'dog', 'husky'][counter++];
}
});
if (a === 'animal' && a === 'dog' && a === 'husky') {
console.log('Haha, husky');
}
现有一段HTML,如下:
Enjoy the <span style='color: #FF6A00; font-style: bold;'>Better</span> <span style='color: #FF6A00;'>Exchange rate</span> by clicking this button.
要求使用正则将标签和文字分隔,分隔结果如下:
"Enjoy the "
"<span style='color: #FF6A00; font-style: bold;'>Better</span>"
" "
"<span style='color: #FF6A00;'>Exchange rate</span>"
" by clicking this button."
创建一个 Promise Chain ,实现有序 Promise 的串行调用:
const promise1 = () => Promise.resolve(1);
const promise2 = () =>
new Promise(resolve => {
setTimeout(() => {
resolve(2);
}, 2000);
});
const promise3 = () =>
new Promise(resolve => {
setTimeout(() => {
resolve(3);
}, 3000);
});
const promiseList = [promise1, promise2, promise3];
/**
* 创建一个 Promise Chain ,实现顺序 Promise 的串行调用
* @param {Array} promiseList Promise 组成的数组
*/
function promiseChain(promiseList) {
// 代码实现
}
promiseChain(promiseList).then(() => {
console.log('所有 Promise 执行完毕。');
});
期望输出结果:
1 // 立即输出
2 // 2s 后输出
3 // 3s 后输出
所有 Promise 执行完毕。
参考答案:
/**
* 创建一个 Promise Chain ,实现顺序 Promise 的串行调用
* @param {Array} promiseList Promise 组成的数组
*/
function promiseChain(promiseList) {
// 实现内容
if (!(Array.isArray(promiseList))) return Promise.reject(new Error('入参错误'));
return promiseList.reduce((pre, cur) => {
return pre.then(() => cur()).then(result => console.log(result));
}, Promise.resolve(0));
}