封装一个异步加载图片的方法

1
2
3
4
5
6
7
8
9
10
11
12
function loadImageUrl(url) {
return new Promise((resolve, reject) {
let img = new Image()
img.onload = function(img) {
resolve('加载图片成功')
}
img.onerror = function() {
reject('can not load image')
}
img.src = url
})
}

请实现一个mergePromise函数,把传进去的数组按顺序先后执行,并且把返回的数据先后放到数组data中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var timeout = ms => new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
var ajax1 = () => timeout(2000).then(() => {
console.log('1');
return 1;
});
var ajax2 = () => timeout(1000).then(() => {
console.log('2');
return 2;
});
var ajax3 = () => timeout(2000).then(() => {
console.log('3');
return 3;
});
var mergePromise = ajaxArray => {
// 在这里实现你的代码
let res = []
var sequence = Promise.resolve()
for (let [i, item] of ajaxArray.entries()) {
sequence = Promise.resolve(item).then(
data => {
res.push(data)
return res
}
)
}
return sequence
};
mergePromise([ajax1, ajax2, ajax3]).then(data => {
console.log('done');
console.log(data); // data 为 [1, 2, 3]
});

// 要求分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]

实现 add 方法,限制同一时刻只能执行2个task

本质就是限制promise并发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const timeout = (time) => new Promise(resolve => {
setTimeout(resolve, time)
})
class Scheduler {
add(fn) {

}
}
const scheduler = new Scheduler()
const addTask = (time, order) => {
scheduler
.add(() => timeout(time))
.then(() => console.log(order))
}

// 限制同一时刻只能执行2个task
addTask(4000, '1')
addTask(3500, '2')
addTask(4000, '3')
addTask(3000, '4')
.....

//Scheduler ?
//4秒后打印1
//3.5秒打印2
//3进入队列,到7.5秒打印3
//...

如何判断是new调用还是函数调用

arguments.callee

1
2
3
4
5
6
7
8
9
function Person() {
if(this.constructor === arguments.callee) {
console.log('new 调用');
}else {
console.log('普通调用');
}
}
let p1 = new Person(); // new 调用
let p2 = Person();

函数重试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 把任意一个函数,修饰生成一个带重试功能的新函数。
* 1、如果执行失败,进行重试;
* 2、如果执行成功,直接返回结果;
* 3、如果重试了 n 次依然失败,抛出最后一次的异常。
* 4、新函数的表现行为要尽可能与原函数保持一致
*
* @param {Function} fn
* @param {number} n 最大重试次数
* @return {Function} 带有重试功能的新函数
*/
function useRetryable(fn, n) {
// TODO
}

函数柯里化

降低通用性,提高适用性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const add = (...rest) => {
return rest.reduce((a,b) => a + b, 0)
}
const curry = (fn) => {
var arr = []
return function temp(...rest) {
if (rest.length) {
arr.push(...rest)
return temp
} else {
let val = fn.apply(this, arr)
arr = []
return val
}
}
}
var addCurry = curry(add)
addCurry(1,2,3,4)()