2018-07-25 汉得日记

Promise对象的继续学习

早上老师又带我们回顾了一下Promise对象的几种用法,但由于讲的比较快。需要在下面自己进行巩固。

1.使用Promise对象的一般写法

设置计时器,并调用reject(),使5s后返回一个rejected状态。然后调用Promise对象的then方法,输出error值。

function timeout(ms) {
    return new Promise((resolve, reject) => {
    setTimeout(reject, ms, 'ljg');
    });
}


timeout(5000).then((value) => {
    console.log(value);
},(error) => {
    console.log(error);
});

下面是一个异步加载图片的,我进行补充的代码:

function loadImageAsync(url) {
    return new Promise(function(resolve, reject) {
    const image = new Image();

    image.onload = function() {
        resolve(image);
    };

    image.onerror = function() {
        reject(new Error('Could not load image at ' + url));
    };

    image.src = url;
    });
}

loadImageAsync('./ss.jpg').then((value) => {
    console.log(value)
},(error) => {
    console.log(error)
});

成功加载后会输出该图片的路径,reject后会输出指定的错误信息。

2.Promise.prototype.catch方法

是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误,总计前面两个Promise对象
console.log('发生错误!', error);
});

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

3.Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

p的状态由p1、p2、p3决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Generator函数

1.yield 表达式

由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

另外需要注意,yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。

(function (){
yield 1;
})()
// SyntaxError: Unexpected number

上面代码在一个普通函数中使用yield表达式,结果产生一个句法错误。

注意,由于next方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法时,传递参数是无效的。V8 引擎直接忽略第一次使用next方法时的参数,只有从第二次使用next方法开始,参数才是有效的。从语义上讲,第一个next方法用来启动遍历器对象,所以不用带有参数
2.for…of 循环

for…of循环可以自动遍历 Generator 函数时生成的Iterator对象,且此时不再需要调用next方法。

function* foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}

for (let v of foo()) {
console.log(v);
}
// 1 2 3 4 5

上面代码使用for…of循环,依次显示 5 个yield表达式的值。这里需要注意,一旦next方法的返回对象的done属性为true,for…of循环就会中止,且不包含该返回对象,所以上面代码的return语句返回的6,不包括在for…of循环之中。

ES6中class的学习

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Point {
constructor() {
    // ...
}

toString() {
    // ...
}

toValue() {
    // ...
}
}

// 等同于

Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};

在类的实例上面调用方法,其实就是调用原型上的方法。

老师上课讲的规范

尽量声明类的时候,把变量提前声明,且static标识的放在第一位:如下述代码:

class Point{
static methods(){};//静态的放在第一位
constructor(x,y)
{
    this.x=x;
this.y=y
}

toString()
{
    return `x y`
}

上述代码可以采用下面代码进行调用:

const poii=new Point()
console.log(poii.toString())
Point.methods();//调用静态

类的静态属性

类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。

class MyClass {
static myStaticProp = 42;

constructor() {
    console.log(MyClass.myStaticProp); // 42
}
}
class的继承
class ColorPoint extends Point {
constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
}

toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}

上面代码中,constructor方法和toString方法之中,都出现了super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值