“20170918 前端开发周报之JS前端开发必看”攻略
前言
“20170918 前端开发周报之JS前端开发必看”是一篇总结了近期前端开发领域重要进展的周报,其中包含了一些值得前端开发者关注的内容和示例。本文将对其中的两个示例进行详细讲解,并分享相应的代码实现。
示例一:用JavaScript实现一个命令行画图程序
该示例介绍了如何使用JavaScript实现一个简单的命令行画图程序,可以通过控制台输入指令来产生不同的图形。下面是具体的实现步骤:
- 首先定义一个对象
canvas
来表示画布,其中包含两个属性:width
表示画布的宽度,height
表示画布的高度。
javascript
const canvas = {
width: 20,
height: 10
};
- 定义一个二维数组
buffer
来表示画布上的每个点存储的值,初始值为0。
javascript
const buffer = [];
for (let i = 0; i < canvas.height; i++) {
buffer[i] = [];
for (let j = 0; j < canvas.width; j++) {
buffer[i][j] = 0;
}
}
- 定义一个函数
render
用于将画布上的点渲染出来,即在控制台打印出一个表示画布的字符串。这个函数通过遍历buffer
数组来实现。
javascript
function render() {
let result = '';
for (let i = 0; i < canvas.height; i++) {
for (let j = 0; j < canvas.width; j++) {
result += buffer[i][j] ? '*' : ' ';
}
result += '\n';
}
console.log(result);
}
- 定义若干个函数来实现不同的绘图指令,比如画水平线、画垂直线、画矩形等等。以画矩形为例:
javascript
function drawRect(x1, y1, x2, y2) {
for (let i = y1; i <= y2; i++) {
for (let j = x1; j <= x2; j++) {
buffer[i][j] = 1;
}
}
}
- 在控制台接收用户输入的指令,并根据指令调用相应的绘图函数。
```javascript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', line => {
const args = line.split(' ');
const command = args.shift();
switch (command) {
case 'rect':
drawRect(...args.map(Number));
render();
break;
// ... 其他绘图指令
}
});
```
示例二:使用ES6重构Promise
该示例介绍了如何使用ES6的新语法重构Promise。ES6让Promise的写法更加简洁、清晰,使得异步编程变得更加易于理解和维护。下面是具体的实现步骤:
- 定义一个类
MyPromise
来表示Promise。
```javascript
class MyPromise {
constructor(executor) {
// ...
}
then(onResolved, onRejected) {
// ...
}
catch(onRejected) {
// ...
}
}
```
- 在
MyPromise
的构造函数中,定义一个变量state
来表示Promise的状态,初始值为'pending'
;定义一个变量value
来存储Promise的结果(成功时是一个值,失败时是一个错误对象);定义一个数组callbacks
来存储所有需要调用的回调函数。
```javascript
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = null;
this.callbacks = [];
// ...
}
then(onResolved, onRejected) {
// ...
}
catch(onRejected) {
// ...
}
}
```
- 在
MyPromise
的构造函数中,定义两个方法resolve
和reject
,分别用来改变Promise的状态为成功或失败,并触发回调函数。
```javascript
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = null;
this.callbacks = [];
const resolve = value => {
if (this.state !== 'pending') {
return;
}
this.state = 'fulfilled';
this.value = value;
this.callbacks.forEach(({ onResolved }) => {
onResolved(value);
});
};
const reject = reason => {
if (this.state !== 'pending') {
return;
}
this.state = 'rejected';
this.value = reason;
this.callbacks.forEach(({ onRejected }) => {
onRejected(reason);
});
};
executor(resolve, reject);
}
then(onResolved, onRejected) {
// ...
}
catch(onRejected) {
// ...
}
}
```
- 在
then
方法中,根据当前Promise的状态来判断是调用onResolved
还是onRejected
。如果状态是成功,调用onResolved
并返回一个新的Promise;如果状态是失败,调用onRejected
并返回一个新的Promise。
```javascript
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = null;
this.callbacks = [];
const resolve = value => {
if (this.state !== 'pending') {
return;
}
this.state = 'fulfilled';
this.value = value;
this.callbacks.forEach(({ onResolved }) => {
onResolved(value);
});
};
const reject = reason => {
if (this.state !== 'pending') {
return;
}
this.state = 'rejected';
this.value = reason;
this.callbacks.forEach(({ onRejected }) => {
onRejected(reason);
});
};
executor(resolve, reject);
}
then(onResolved, onRejected) {
return new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
try {
const result = onResolved(this.value);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
} else if (this.state === 'rejected' && onRejected) {
try {
const result = onRejected(this.value);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
} else {
this.callbacks.push({ onResolved, onRejected });
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
```
- 在
catch
方法中,调用then
方法,传入null
作为onResolved
,并传入onRejected
作为onRejected
,从而实现捕获Promise的异常情况。
```javascript
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = null;
this.callbacks = [];
const resolve = value => {
if (this.state !== 'pending') {
return;
}
this.state = 'fulfilled';
this.value = value;
this.callbacks.forEach(({ onResolved }) => {
onResolved(value);
});
};
const reject = reason => {
if (this.state !== 'pending') {
return;
}
this.state = 'rejected';
this.value = reason;
this.callbacks.forEach(({ onRejected }) => {
onRejected(reason);
});
};
executor(resolve, reject);
}
then(onResolved, onRejected) {
return new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
try {
const result = onResolved(this.value);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
} else if (this.state === 'rejected' && onRejected) {
try {
const result = onRejected(this.value);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
} else {
this.callbacks.push({ onResolved, onRejected });
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
```
以上就是使用ES6重构Promise的实现过程。重构后的Promise更加简洁易懂,可以让我们更加方便地进行异步编程。
总结
本文对“20170918 前端开发周报之JS前端开发必看”中的两个示例进行了详细的讲解,包括命令行画图程序的实现和Promise重构的实现。希望读者通过这两个示例,掌握一些新的前端开发技巧和思路。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:20170918 前端开发周报之JS前端开发必看 - Python技术站