Shang Silicon Valley ES6 review summary (64th)

1. let keyword

The let keyword is used to declare variables. Variables declared using let have several characteristics:

1. Duplicate declarations are not allowed
2. Block-level scope

 if (true) {
    
    
    let a = 10;
}
console.log(a) // a is not defined

3. There is no variable promotion

 console.log(a); //报错
 let a = 20;

4. Does not affect the scope chain

It is right to declare variables in the future using let

Case 1: Register click events for multiple div loops

// 错误示例,divs.length === 3
document.addEventListener('DOMContentLoaded', function () {
    
    
    let divs = document.querySelectorAll('.box div');
    for (var i = 0; i < divs.length; i++) {
    
    
        divs[i].addEventListener('click', function () {
    
    
            divs[i].style.backgroundColor = 'pink';
        });
    }
    console.log(i); // 3
});
/*
i 为当前作用域下的共享变量。
当每次点击 div 的时候,各个点击事件共享 i 的值。
此时 i = 3,这将报错。
*/

Correct example: Change var in the above code to let.

Case 2: After 1s, output all numbers in a loop
Error example:

for (var i = 1; i <= 5; i++) {
    
    
    setTimeout(() => {
    
    
        console.log(i);
    }, 1000);
}
/*
输出:6 6 6 6 6
循环从1-5的时间很短暂,远不及 1s。
此时五个异步事件瞬间加入到异步事件队列中,等待 1s后依次执行。
而此时i为6,故瞬间输出 5 个 6。
异步事件队头
(1) console.log(i);
(2) console.log(i);
(3) console.log(i);
(4) console.log(i);
(5) console.log(i);
*/

Correct example:

for (let j = 1; j <= 5; j++) {
    
    
    setTimeout(() => {
    
    
        console.log(j);
    }, 1000);
}
// 输出:1 2 3 4 5
// let 有块级作用域,每个 j 都会形成一个自己的块级作用域,与相应的异步事件共享:
// {j = 1;} {j = 2;} {j = 3;} {j = 4;} {j = 5;}

Solution 2:

// 给每一个 i 设置一个立即执行函数,会形成自己的块级作用域,不影响外部变量。
for (var i = 1; i <= 5; i++) {
    
    
    (function (i) {
    
    
        setTimeout(() => {
    
    
            console.log(i);
        }, 1000);
    })(i);
}

2. The const keyword

The const keyword is used to declare constants. The const declaration has the following characteristics:

1. The statement must be assigned an initial value

const test; // Missing initializer in const declaration

2. Identifiers are generally uppercase (hidden rules, lowercase is also acceptable)
3. Repeated declarations are not allowed
. 4. Values ​​are not allowed to be modified, but the modification of elements of arrays and objects is not considered as modification of constants, and no error will be reported. Reason The address has not changed
5. Block-level scope

Application scenario: declare object type using const, non-object type declaration choose let

3. Destructuring assignment

ES6 allows to extract values ​​from arrays and objects and assign values ​​to variables according to a certain pattern, which is called destructuring assignment.

1. Array deconstruction assignment

const arr = ['red', 'green', 'blue'];
let [r, g, b] = arr;

2. Object deconstruction assignment

const obj = {
    
    
    uname: 'rick',
    age: 30,
    sayHi: function () {
    
    
        console.log('hello');
    },
    sayBye() {
    
    
        console.log('Bye~');
    }
}
let {
    
    name, age, sayHi} = obj;
let {
    
    sayBye} = obj;

Application scenario: Frequent use of object methods and array elements can use the form of destructuring assignment.

4. Template strings

The template string (template string) is an enhanced version of the string, identified by backticks `, features:

1. Newline characters can appear in the string

let ul = `<ul>
    <li>apple</li>
    <li>banana</li>
    <li>peach</li>
    </ul>`

2. You can use ${xxx}the form to output variables (this ${} is a fixed way of writing)

let name = 'jack';
console.log(`hello, ${
      
      name}`);

Application scenario: Use template strings when strings and variables are concatenated.

5. Simplified object writing

ES6 allows variables and functions to be written directly inside curly braces as properties and methods of objects. This writing is more concise.

let name = 'tianyang'; 
let slogon = '一点一滴都是进步'; 
let improve = function () {
    
     console.log('学习可以提高你的技能'); }
//属性和方法简写
let xuexi = {
    
     
    name,//name:name的简化
    slogon,
    improve(){
    
    console.log('学习可以提高你的技能');}//improve:function () { console.log('学习可以提高你的技能'); }的简化
   
};
console.log(xuexi)

6. Arrow functions

ES6 allows functions to be defined using () => {}.

function writing

function fn(param1, param2,, paramN) {
    
     
    // 函数体
    return expression; 
}

Arrow function writing

let fn = (param1, param2,, paramN) => {
    
    
    // 函数体
    return expression;
}

Points to note about arrow functions:

1. If there is only one formal parameter, the parentheses can be omitted.
2. If the function body has only one statement, the curly braces can be omitted. The return value of the function is the execution result of the statement.
3. The arrow function this always points to the function when it is declared The value of this under the domain
4. Arrow functions cannot be instantiated as constructors
5. Arguments cannot be used

// 省略小括号
let fn1 = n => {
    
    
    return n * n;
}

// 省略花括号
let fn2 = (a + b) => a + b;    //return也不能写

// 箭头函数 this 始终指向声明时所在作用域下 this 的值
const obj = {
    
    
    a: 10,
    getA () {
    
    
        let fn3 = () => {
    
    
            console.log(this); // obj {...}
            console.log(this.a); // 10
        }
        fn3();
    }

}

Case 1: The this of the arrow function always points to the value of this in the scope where it is declared, and methods such as call cannot change its point.

let obj = {
    
    
    uname: 'rick',
    age: 30
};
let foo = () => {
    
    
    console.log(this);
}
let bar = function () {
    
    
    console.log(this);
}
// call 对箭头函数无效
foo.call(obj); // window
bar.call(obj); // obj {...}

Case 2: Screen even numbers

let arr = [2, 4, 5, 10, 12, 13, 20];
let res = arr.filter(v => v % 2 === 0);
console.log(res); // [2, 4 , 10, 12, 20]

Case 3: Click the div to turn pink after two seconds

Solution 1: Use _this to save the this under the div, so as to set the style attribute of the div.

div.addEventListener('click', function () {
    
    
    let _this = this;  //不这样做this就指向window,现在指向div
    setTimeout(function () {
    
    
        console.log(_this); // <div>...<div>
        _this.style.backgroundColor = 'pink';
    }, 2000)
});

Solution 2: Use => arrow function

div.addEventListener('click', function () {
    
    
    setTimeout(() => {
    
    
        console.log(this); // <div>...</div>
        this.style.backgroundColor = 'pink';
    }, 2000);
});

Arrow functions are suitable for callbacks that have nothing to do with this, timers, and array method callbacks.
Arrow functions are not suitable for callbacks that are related to this, event callbacks, and object methods

7. Function parameter default value setting

ES6 allows setting default values ​​​​for function parameters. When the function is called without an actual parameter, the default value of the parameter is used.

Formal parameters with default values ​​generally come later.

let add = (x, y, z=3) => x + y + z;
console.log(add(1, 2)); // 6

Can be combined with destructuring assignment:

function connect({
    
     host = '127.0.0.1', uesername, password, port }) {
    
    
    console.log(host); // 127.0.0.1
    console.log(uesername);
    console.log(password);
    console.log(port);
}
connect({
    
    
    // host: 'docs.mphy.top',
    uesername: 'root',
    password: 'root',
    port: 3306
})

8. rest parameters

ES6 introduces the rest parameter, which is used to obtain the actual parameters of the function, which is used to replace arguments, and its function is similar to arguments. Convert the received parameter sequence into an array object.

It is used in function parameters, the syntax format is: fn(a, b, ...args), written at the end of the parameter list.

let fn = (a, b, ...args) => {
    
    
    console.log(a);
    console.log(b);
    console.log(args);
};
fn(1,2,3,4,5);
/*
1
2
[3, 4, 5]   返回的是一个数组,而arguments返回的是对象
*/

Case 1: Find the sum of an indefinite number of numbers

let add = (...args) => {
    
    
//reduce() 方法接收一个函数作为累加器,reduce 为数组中的每一个元素依次执行回调函数
//接受四个参数:初始值(上一次回调的返回值),当前元素值,当前索引,原数组
    let sum = args.reduce((pre, cur) => pre + cur, 0);
    return sum;
}
console.log(add(1, 2, 3, 4, 5)); // 15

Application scenarios: rest parameters are very suitable for scenarios with variable number of parameter functions

9. spread spread operator

The spread operator (spread) is also three dots (…). It is like the inverse operation of the rest parameter, converting an array into a sequence of parameters separated by commas, and unpacking the array. It can be used to convert an array into a parameter sequence by passing the actual parameters when calling the function.

The spread operator can also unpack objects.

 let arr = [1, 2, 3];
 /*...arr*/  // 1, 2, 3
 console.log(...arr);    // 1 2 3
 //等同于
 console.log(1, 2, 3)

Case 1: Array merge

// 方法一 
let A = [1, 2, 3];
let B = [4, 5, 6];
let C = [...A, ...B];
console.log(C); // [1, 2, 3, 4, 5, 6]
// 方法二 
A.push(...B);

Case 2: Array cloning
This type of array cloning is a shallow copy.

let arr1 = ['a', 'b', 'c'];
let arr2 = [...arr1];
console.log(arr2); // ['a', 'b', 'c']

Case 3: Convert pseudo-array to real array

const divs = document.querySelectorAll('div');   //是一个对象
let divArr = [...divs];  //变成了数组
console.log(divArr);

Case 4: Object Merging

// 合并对象
let obj1 = {
    
    
    a: 123
};
let obj2 = {
    
    
    b: 456
};
let obj3 = {
    
    
    c: 789
};
let obj = {
    
     ...obj1, ...obj2, ...obj3 };
console.log(obj);
// { a: 123, b: 456, c: 789 }

10. Symbol data type

ES6 introduces a new primitive data type Symbol, representing a unique value. It is the seventh data type of the JavaScript language and is a data type similar to strings.

The seven basic data types of JavaScript:

1. Value type (basic type): string, number, boolean, undefined, null, symbol
2. Reference data type: object (including array, function)

Symbol features:

1. The value of Symbol is unique, which is used to solve the problem of naming conflicts.
2. The value of Symbol cannot be operated with other data .
3. The object properties defined by Symbol cannot be for...intraversed , but you can use Reflect.ownKeysto get all the key names of the object

1. How to create Symbol:

//创建一个 Symbol
let s1 = Symbol();
console.log(s1, typeof s1);    // Symbol() symbol

//添加具有标识的 Symbol 
let s2 = Symbol('1');
let s2_1 = Symbol('1');
console.log(s2 === s2_1);    // false  Symbol 都是独一无二的

//使用 Symbol.for() 方法创建,名字相同的 Symbol 具有相同的实体。
let s3 = Symbol.for('apple');
let s3_1 = Symbol.for('apple');
console.log(s3 === s3_1); // true

//输出 Symbol 变量的描述,使用 description 属性
let s4 = Symbol('测试');
console.log(s4.description); // 测试

11. Objects add properties of type Symbol

Case : Safely add properties and methods to objects.
Analysis : If you add a property or method directly to the object, the property or method with the same name may already exist in the original object, and the original one will be overwritten. Therefore, using Symbol to generate a unique property or method name can be added more safely.

Code:

// 这是一个 game 对象,假设我们不知道里面有什么属性和方法
const game = {
    
    
    uname: '俄罗斯方块',
    up: function () {
    
     },
    down: function () {
    
     }
}

// 通过 Symbol 生成唯一的属性名,然后给 game 添加方法
let [up, down] = [Symbol('up'), Symbol('down')];
game[up] = function () {
    
    
    console.log('up');
}
game[down] = function () {
    
    
    console.log('down');
}

// 调用刚刚创建的方法
game[up]();
game[down]();

12. Symbol built-in value

In addition to defining the Symbol value used by itself, ES6 also provides 11 built-in Symbol values, which point to the methods used internally by the language. These methods can be called magic methods, because they will be executed automatically in certain scenarios.

insert image description here
Case 1: Symbol.hasInstanceThe method is called when judging whether it belongs to this object.

class A {
    
    
    static [Symbol.hasInstance]() {
    
    
        console.log('判断是否属于这个对象时被调用');
    }
}
let obj = {
    
    };
console.log(obj instanceof A
// 判断是否属于这个对象时被调用
// false

Case 2: When the array uses the concat method, whether it can be expanded.

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr1.concat(arr2));
// [ 1, 2, 3, [ 4, 5, 6, [Symbol(Symbol.isConcatSpreadable)]: false ] ]
console.log(arr1.concat(arr3));
// [ 1, 2, 3, 4, 5, 6 ]

13. Iterators

Iterator (Iterator) is a mechanism. It is an interface that provides a unified access mechanism for various data structures. Any data structure can complete the traversal operation as long as Iteratorthe interface .

1. ES6 creates a new traversal command for...ofloop , Iteratorthe interface is mainly for for...ofconsumption .
2. Native data with iterator interface (can be traversed with for of)

1.Array
2.Arguments
3.Set
4.Map
5.String
6.TypedArray
7.NodeList

Working principle
1. Create a pointer object to point to the starting position of the current data structure
2. Call the next method of the object for the first time, and the pointer will automatically point to the first member of the data structure
3. Next, call the next method continuously, and the pointer will go all the way After moving until it points to the last member
4. Each call to the next method returns an object containing value and done attributes

Application scenario: When you need to customize the traversal data, you must think of iterators.

Custom traversal data
We can enable the data structure to be traversed directly by adding a custom [Symbol.iterator]()method , so that for...ofcan directly traverse the specified data to achieve the function of for...ofserving .

// 需求:遍历对象中的数组
const xiaomi = {
    
    
    uname: '小明',
    course: [ '高数', '大物', '英语', '数据库' ],
    // 通过自定义 [Symbol.iterator]() 方法
    [Symbol.iterator]() {
    
    
        // 初始指针对象指向数组第一个
        let index = 0;
        // 保存 xiaomi 的 this 值
        let _this = this;
        return {
    
    
            next: function () {
    
    
                // 不断调用 next 方法,直到指向最后一个成员
                if (index < _this.course.length) {
    
    
                    return {
    
     value: _this.course[index++], done: false };
                } else {
    
    
                    // 每调用next 方法返回一个包含value 和done 属性的对象
                    return {
    
     value: undefined, done: true };
                }
            }
        }
    }
}
// for...of直接遍历达到目的
for (let v of xiaomi) {
    
    
    console.log(v);
}

14. Generator generator function

Generator functions are an asynchronous programming solution provided by ES6, and the syntax behavior is completely different from traditional functions.

1. *There is no limit to the location
of the 2. Use function * gen()and yieldYou can declare a generator function. The result returned by the generator function is an iterator object, and the value after the statement can be obtained by calling nextthe method . 3. Each is equivalent to the pause mark of the function, and can also be regarded as a separator. Every time it is called , the generator function will execute a section down. 4. The method can pass actual parameters as the return value of the statementyield
yieldnext()
nextyield

For example, in the following generator function, 3 yieldstatements divide the function into 4 sections.

function* generator() {
    
    
    console.log('before 111'); // 生成器第 1 段
    yield 111;
    console.log('before 222'); // 生成器第 1 段
    yield 222;
    console.log('before 333'); // 生成器第 1 段
    yield 333;
    console.log('after 333'); // 生成器第 1 段
}
let iter = generator();
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
/*
before 111
{ value: 111, done: false }
before 222
{ value: 222, done: false }
before 333
{ value: 333, done: false }
after 333
{ value: undefined, done: true }
*/

Generator function parameter passing

function* generator(arg) {
    
    
    console.log(arg); // 生成器第 1 段
    let one = yield 111;
    console.log(one); // 生成器第 2 段
    let two = yield 222;
    console.log(two); // 生成器第 3 段
    let three = yield 333; 
    console.log(three); // 生成器第 4 段
}

let iter = generator('aaa'); // 传给生成器第 1 段
console.log(iter.next());
console.log(iter.next('bbb')); // 传给生成器第 2 段,作为这一段开始的 yield 语句返回值
console.log(iter.next('ccc')); // 传给生成器第 3 段,作为这一段开始的 yield 语句返回值
console.log(iter.next('ddd')); // 传给生成器第 4 段,作为这一段开始的 yield 语句返回值
/*
aaa
{ value: 111, done: false }
bbb
{ value: 222, done: false }
ccc
{ value: 333, done: false }
ddd
{ value: undefined, done: true }
*/

15. Generator function example

Case 1: output 111 after 1s, output 222 after 2s, output 333 after 3s

Traditional way: too much nesting, complex code, and callback hell.

setTimeout(() => {
    
    
    console.log(111);
    setTimeout(() => {
    
    
        console.log(222);
        setTimeout(() => {
    
    
            console.log(333);
        }, 3000);
    }, 2000);
}, 1000);

Generator implementation: simple and clear structure

function one() {
    
    
    setTimeout(() => {
    
    
        console.log(111);
        iter.next();
    }, 1000);
}

function two() {
    
    
    setTimeout(() => {
    
    
        console.log(222);
        iter.next();
    }, 2000);
}

function three() {
    
    
    setTimeout(() => {
    
    
        console.log(333);
        iter.next();
    }, 3000);
}

function* generator() {
    
    
    yield one();
    yield two();
    yield three();
}

let iter = generator();
iter.next();

Case 2: The generator function simulates getting product data every 1s

function getUsers() {
    
    
    setTimeout(() => {
    
    
        let data = '用户数据';
        iter.next(data); // 传参给生成器函数的第 2 段,后面类似
    }, 1000);
}

function getOrders() {
    
    
    setTimeout(() => {
    
    
        let data = '订单数据';
        iter.next(data);
    }, 1000);
}

function getGoods() {
    
    
    setTimeout(() => {
    
    
        let data = '商品数据';
        iter.next(data);
    }, 1000);
}

function* generator() {
    
    
    let users = yield getUsers();
    console.log(users);
    let orders = yield getOrders();
    console.log(orders);
    let goods = yield getGoods();
    console.log(goods);
}

let iter = generator();
iter.next();

16. Promise

1. Definition and use of Promise

Promiseis a new solution for asynchronous programming introduced by ES6. Syntactically Promiseis a constructor that encapsulates an asynchronous operation and can get its success or failure result.

A Promise must be in one of the following states:

1. Pending: The initial state, which has neither been redeemed nor rejected.
2. Fulfilled: means the operation was successfully completed.
3. Rejected: means the operation failed.

Promise usage:

1. Promise constructor: new Promise((resolve, reject)=>{})
2. Promise.prototype.thenMethod
3. Promise.prototype.catchMethod

A simple case:

let p = new Promise(function (resolve, reject) {
    
    
    // 使用 setTimeout 模拟请求数据库数据操作
    setTimeout(function () {
    
    
        // 这个异步请求数据库数据操作是否正确返回数据
        let isRight = true;
        if (isRight) {
    
    
            let data = '数据库中的数据';
            // 设置 Promise 对象的状态为操作成功
            resolve(data);
        } else {
    
    
            let err = '数据读取失败!'
            // 设置 Promise 对象的状态为操作失败
            reject(err);
        }
    }, 1000);
});
p.then(function (value) {
    
    
    console.log(value);
}, function (reason) {
    
    
    console.error(reason);
})

2. Promise package read file

// 使用 nodejs 的 fs 读取文件模块
const fs = require('fs');

const p = new Promise(function (resolve, reject) {
    
    
    fs.readFile('./resources/为学.txt', (err, data) => {
    
    
        // err 是一个异常对象
        if (err) reject(err);
        // 如果成功
        resolve(data);
    })
})

p.then(function (value) {
    
    
    // 转为字符串输出
    console.log(value.toString());
}, function (reason) {
    
    
    console.log('读取失败!!');
})

3. Promise encapsulates Ajax requests

const p = new Promise((resolve, reject) => {
    
    
    const xhr = new XMLHttpRequest();
    xhr.open('get', 'https://api.apiopen.top/getJoke');
    xhr.send();
    xhr.onreadystatechange = function () {
    
    
        if (xhr.readyState === 4) {
    
    
            if (xhr.status >= 200 && xhr.status < 300) {
    
    
                // 成功
                resolve(xhr.response);
            } else {
    
    
                // 失败
                reject(xhr.status);
            }
        }
    }
});

// 指定回调
p.then(function (value) {
    
    
    console.log(value);
}, function (reason) {
    
    
    console.error(reason);
})

4, Promise.prototype.then method

First review the three states of a Promise:

1. Pending: The initial state, which has neither been redeemed nor rejected.
2. Fulfilled: means the operation was successfully completed.
3. Rejected: means the operation failed.

Promise.prototype.thenThe result returned by the method is still a Promise object, and the state of the object is determined by the execution result of the callback function.

The details are as follows:
1. If thenthe method does not return a value, thenthe status value of the object returned by the method is success fulfilled, and the returned result value isundefined

const p = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        // resolve('用户数据')
        reject('出错了');
    }, 1000);
})
// 未设定返回值
const res = p.then((value) => {
    
    
    console.log(value);
}, (reason) => {
    
    
    console.warn(reason);
})
// 打印 then 方法的返回值
console.log(res);

2. If the result returned in the callback function is a non Promise-type attribute, thenthe status of the object returned by the method is success (fulfilled), and the returned result value depends on which function (resolve or reject) thenthe method executes.

const p = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        // resolve('用户数据')
        reject('出错了');
    }, 1000);
})
 // 返回的非 Promise 对象
const res = p.then((value) => {
    
    
    console.log(value);
    return '成功了!!';
}, (reason) => {
    
    
    console.warn(reason);
    return '出错啦!!'
})
// 打印 then 方法的返回值
console.log(res);

3. If the result returned in the callback function is Promiseof type (return new Promise()), then the state of the Promise object returned by the then method is the same as the state of the returned result, and the return value is also the same.

const p = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve('用户数据')
        // reject('出错了');
    }, 1000);
})
const res = p.then((value) => {
    
    
    console.log(value);
    // 返回 Promise 对象
    return new Promise((resolve, reject) => {
    
    
        resolve('(1)成功了!!!');
        // reject('(1)出错了!!!')
    })
}, (reason) => {
    
    
    console.warn(reason);
    return new Promise((resolve, reject) => {
    
    
        // resolve('(2)成功了!!!');
        reject('(2)出错了!!!')
    })
})
// 打印 then 方法的返回值
console.log(res);

4. If the result returned in the callback function is that throwthe statement throws an exception, then thenthe state value of the object of the method is rejected, and the returned result value is the literal value throwthrown by or Errorthe object.

const p = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve('用户数据');
    }, 1000);
});
const res = p.then((value) => {
    
    
    console.log(value);
    return new Promise((resolve, reject) => {
    
    
        throw new Error('错误了!!');
    })
});
// 打印结果
console.log(res);

5. Chain call

Promise.prototype.thenThe result returned by the method is still Promisean object , which means we can continue to use thenthe method on the result, that is, chain calls.

const p = new Promise(resolve=>{
    
    }, reject=>{
    
    });
p.then(value=>{
    
    }, reason=>{
    
    })
.then(value=>{
    
    }, reason=>{
    
    })
.then(value=>{
    
    }, reason=>{
    
    })
...

6. Chain call practice - reading multiple files

const fs = require('fs');

let p = new Promise((resolve, reject) => {
    
    
    fs.readFile('./resources/users.md', (err, data) => {
    
    
        // 传给下一轮文件读取操作
        resolve(data);
    })
});

p.then(value => {
    
    
    return new Promise((resolve, reject) => {
    
    
        // value 为第一次读取的文件数据,data 为第二次(当前)读取的数据
        fs.readFile('./resources/orders.md', (err, data) => {
    
    
            // 将上轮读取结果和本轮合并传到下一轮轮读取操作
            resolve([value, data]);
        });
    });
}).then(value => {
    
    
    return new Promise((resolve, reject) => {
    
    
        fs.readFile('./resources/goods.md', (err, data) => {
    
    
            // value 为上一轮传递过来的文件数据数组
            value.push(data);
            // 传给下一轮操作
            resolve(value);
        });
    });
}).then(value => {
    
    
    // 合并数组元素,输出
    console.log(value.join('\n'));
});

7、Promise.prototype.catch

catch()method returns one Promise, and handles the case of rejection. It behaves Promise.prototype.then(undefined, onRejected)the same .
Right now:

obj.catch(onRejected);

Equivalent to:

obj.then(undefined, onRejected);

grammar:

p.catch(onRejected);

p.catch(function(reason) {
    
    
   // 拒绝
});

Example:

var p1 = new Promise(function (resolve, reject) {
    
    
    resolve('Success');
});

p1.then(function (value) {
    
    
    console.log(value); // "Success!"
    throw 'oh, no!';
}).catch(function (e) {
    
    
    console.log(e); // "oh, no!"
}).then(function () {
    
    
    console.log('有 catch 捕获异常,所以这句输出');
}, function () {
    
    
    console.log('没有 catch 捕获异常,这句将不会输出');
});

Output result:

Success
oh, no!
有 catch 捕获异常,所以这句输出

おすすめ

転載: blog.csdn.net/weixin_55608297/article/details/128087829