当前位置: 首页 > news >正文

javascript之Es6八股文

说说var、let、const之间的区别

比较项varletconst
变量提升存在,声明提升到作用域顶部,值不提升,声明前使用为undefined不存在,必须先声明后使用,否则报错不存在,必须先声明后使用,否则报错
暂时性死区不存在存在,从块级作用域开始到声明变量的代码行之间,变量不可用,访问报错存在,从块级作用域开始到声明变量的代码行之间,变量不可用,访问报错
块级作用域不存在,在函数作用域或全局作用域有效存在,声明的变量仅在所在块级作用域内有效存在,声明的变量仅在所在块级作用域内有效
重复声明允许在同一作用域重复声明,后声明覆盖先声明的值在同一作用域不允许重复声明,否则报错在同一作用域不允许重复声明,否则报错
修改声明的变量声明的变量值可修改声明的变量值可修改声明的是常量,值不能改变(简单类型);复杂类型指针固定,内部结构可改变
使用建议尽量避免使用,可能带来因变量提升和缺乏块级作用域导致的问题大多数情况下使用,尤其是需要块级作用域和变量可修改场景能用const尽量用,保证数据不可变性,增强代码稳定性和可维护性

 

ES6中数组新增了哪些扩展?

分类新增内容说明
扩展运算符用于函数调用、数据结构转换、数组操作及解构赋值结合将数组转为参数序列;转某些数据结构为数组;实现数组复制、合并;与解构赋值结合生成数组,在数组赋值时只能在最后一位
构造函数新增方法Array.from()将类似数组或可遍历对象转为数组,可对元素处理
Array.of()将一组值转为数组,无参返回空数组,单参指定长度,多参组成新数组
实例对象新增方法copyWithin(target, start, end)将指定位置成员复制到其他位置,返回当前数组
find(callback)、findIndex(callback)find 找出首个符合条件成员;findIndex 返回首个符合条件成员位置,不符则返回 -1,均可绑定 this
fill(value, start, end)用给定值填充数组,可指定范围,填充对象为浅拷贝
entries()、keys()、values()分别用于键值对、键名、键值的遍历
includes(value, fromIndex)判断数组是否包含给定值,可指定起始位置
flat(depth)、flatMap(callback, thisArg)flat 扁平化数组,可指定深度;flatMap 先执行函数再扁平化,可绑定 this
数组的空位ES6 将空位转为 undefined涉及多个方法,建议避免空位
排序稳定性sort () 默认稳定排序算法排序后元素相对顺序与原始顺序一致

一、扩展运算符(...)

  • 作为函数参数:将数组转为逗号分隔的参数序列,用于函数调用。
function push(array, ...items) {array.push(...items);
}
function add(x, y) {return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
  • 数据结构转换:可将某些数据结构转为数组,如NodeList、定义了遍历器(Iterator)接口的对象。字符串也可借此转为数组。
[...document.querySelectorAll('div')]
[...'hello'] // [ "h", "e", "l", "l", "o" ]
  • 数组操作
    • 复制数组:实现简单数组复制,但为浅拷贝。
const a1 = [1, 2];
const [...a2] = a1; // [1,2]
  • 合并数组:简洁实现数组合并。
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
[...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]
  • 解构赋值结合:可与解构赋值结合生成数组,但扩展运算符在数组赋值时只能放在参数最后一位。
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]

 

二、构造函数新增方法

  • Array.from():将类似数组的对象和可遍历(iterable)的对象转为真正的数组,可接受第二个参数对每个元素进行处理。
let arrayLike = {'0': 'a','1': 'b','2': 'c',length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
  • Array.of():将一组值转换为数组,无参数时返回空数组,单个参数时指定数组长度不少于 2 个参数时返回由参数组成的新数组。
Array.of(3, 11, 8) // [3,11,8]
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

 

三、实例对象新增方法

  1. copyWithin():将指定位置成员复制到其他位置(覆盖原有成员),返回当前数组。
    • 参数:
      • target(必需):替换起始位置,负值表示倒数。
      • start(可选):读取数据起始位置,默认为 0,负值从末尾计算。
      • end(可选):读取数据停止位置,默认数组长度,负值从末尾计算。
    • 示例:
[1, 2, 3, 4, 5].copyWithin(0, 3) // 将从 3 号位直到数组结束的成员(4 和 5),复制到从 0 号位开始的位置,结果覆盖了原来的 1 和 2
// [4, 5, 3, 4, 5] 
  1. find()、findIndex()
    • find():找出第一个符合条件数组成员,参数为回调函数(接受当前值、当前位置、原数组)。
    • findIndex():返回第一个符合条件的数组成员位置,都不符合则返回 -1。
    • 均可接受第二个参数绑定回调函数的this对象。
    • 示例:
[1, 5, 10, 15].find(function (value, index, arr) {return value > 9;
}) // 10
[1, 5, 10, 15].findIndex(function (value, index, arr) {return value > 9;
}) // 2
function f(v) {return v > this.age;
}
let person = { name: 'John', age: 20 };
[10, 12, 26, 15].find(f, person); // 26
  1. fill():使用给定值填充数组,可接受第二、三个参数指定填充起始和结束位置,填充对象时为浅拷贝。
['a', 'b', 'c'].fill(7) // [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
  1. entries(),keys(),values()
    • keys():键遍历。
    • values():键遍历。
    • entries():键值对遍历。
    • 示例:(let  of)
for (let index of ['a', 'b'].keys()) {console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {console.log(index, elem);
}
// 0 "a"
  1. includes():判断数组是否包含给定值,第二个参数表示搜索起始位置,默认为 0,负数表示倒数位置。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
  1. flat(),flatMap()
    • flat()扁平化数组,返回新数组,默认 “拉平” 一层,可传入整数指定拉平层数。
    • flatMap():先对原数组每个成员执行函数(类似map),再对返回值数组执行flat(),返回新数组,不改变原数组,可接受第二个参数绑定this。新旧都有
    • 示例:
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
[2, 3, 4].flatMap((x) => [x, x * 2]) // [2, 4, 3, 6, 4, 8]

 

四、数组的空位

ES6 将数组空位明确转为undefined,涉及方法包括Array.from、扩展运算符、copyWithin()fill()entries()keys()values()find()findIndex(),建议书写时避免出现空位。

 

五、排序稳定性

sort()默认设置为稳定的排序算法,排序结果中元素相对顺序与原始顺序一致。

const arr = ['peach','straw','apple','spork'
];
const stableSorting = (s1, s2) => {if (s1[0] < s2[0]) return -1;return 1;
};
arr.sort(stableSorting)
// ["apple", "peach", "straw", "spork"]

 

ES6中对象新增了哪些扩展?

分类内容说明示例
属性的简写

键值对方法简写

当对象键名与对应值名相等时可简写;对象、方法也能简写键值对简写:
const baz = { foo };
等同于 
const baz = {foo: foo};
方法简写:
const o = {method() {return "Hello!";}
};
// 等同于
const o = {method: function() {return "Hello!";}
};
函数返回值简写:
function getPoint() {const x = 1;const y = 10;return { x, y };
}
getPoint();
// {x:1, y:10}
属性名表达式

定义属性与方法名

字面量定义对象时,表达式放括号内作属性名,也可定义方法名let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word']; // "hello"
a[lastWord]; // "world"
a['last word']; // "world"

let obj = {
['h' + 'ello']() {
return 'hi';
}
};
obj.hello(); // hi
super 关键字

指向原型对象

super指向当前对象的原型对象const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find(); // "hello"
扩展运算符的应用

解构赋值与对象合并

解构赋值时,未读取的可遍历属性分配到指定对象,必须是最后一个参数且为浅拷贝;对象扩展运算符等同于Object.assign()方法解构赋值:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }

let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b; // 2
属性的遍历

五种遍历方法及次序规则

  • for...in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)

  • Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名

  • Object.getOwnPropertyNames(obj):回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名

  • Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名

  • Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

先数值键(升序),再字符串键(加入时间升序),最后 Symbol 键(加入时间升序)
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]

 

对象新增的方法

Object.is()

严格判断两值相等,与===基本一致,+0不等于-0NaN等于自身

+0 === -0; //true
NaN === NaN; // false
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true

Object.assign()

对象合并,将源对象可枚举属性复制到目标对象,浅拷贝,同名属性替换

const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target; // {a:1, b:2, c:3}

Object.getOwnPropertyDescriptors()

返回指定对象所有自身属性(非继承)的描述对象

const obj = {
foo: 123,
get bar() { return 'abc' }
};
Object.getOwnPropertyDescriptors(obj);
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }

Object.setPrototypeOf()

设置一个对象的原型对象

const o = Object.setPrototypeOf({}, null);

Object.getPrototypeOf()

读取一个对象的原型对象

Object.getPrototypeOf(obj);

Object.keys()

返回自身(不含继承)所有可遍历属性键名的数组

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj);
// ["foo", "baz"]

Object.values()

返回自身(不含继承)所有可遍历属性键对应的数组

const obj = { foo: 'bar', baz: 42 };
Object.values(obj);
// ["bar", 42]

Object.entries()

返回对象自身(不含继承)所有可遍历属性键值对的数组

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj);
// [ ["foo", "bar"], ["baz", 42] ]

Object.fromEntries()

将键值对数组转为对象

Object.fromEntries([
['foo', 'bar'],
['baz', 42]
]);
// { foo: "bar", baz: 42 }

 

ES6中函数新增了哪些扩展?

一、参数

  • 默认值:ES6 允许为函数参数设置默认值。
function log(x, y = 'World') {console.log(x, y);
}console.log('Hello') // Hello World
console.log('Hello', 'China') // Hello China
console.log('Hello', '') // Hello
  • 声明限制:函数形参默认声明,不能用letconst再次声明。
function foo(x = 5) {let x = 1; // errorconst x = 2; // error
}
  • 与解构赋值结合:参数默认值可与解构赋值默认值联用。注意参数为对象时才能解构,无参数时会报错,可通过设置外层默认值避免。
// 未设置外层默认值
function foo({x, y = 5}) {console.log(x, y);
}
foo({}); // undefined 5
foo({x: 1}); // 1 5
foo({x: 1, y: 2}); // 1 2
foo(); // TypeError: Cannot read property 'x' of undefined// 设置外层默认值
function foo({x, y = 5} = {}) {console.log(x, y);
}
foo(); // undefined 5
  • 位置限制:参数默认值应是尾参数,非尾部参数设默认值实际不可省略。
function f(x = 1, y) {return [x, y];
}
f(); // [1, undefined]
f(2); // [2, undefined]
f(, 1); // 报错
f(undefined, 1); // [1, 1]

二、属性

  • length 属性:返回未指定默认值的参数个数,rest 参数不计入,非尾参数设默认值时,后面参数也不计入。
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
(function(...args) {}).length // 0
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
  • name 属性:返回函数名。具名函数赋值给变量,name返回具名函数原本名字;Function构造函数返回的实例,name"anonymous"bind返回的函数,name值加"bound"前缀。
var f = function () {};
// ES5
f.name // ""
// ES6
f.name // "f"const bar = function baz() {};
bar.name // "baz"(new Function).name // "anonymous"function foo() {};
foo.bind({}).name // "bound foo"(function(){}).bind({}).name // "bound "

三、作用域

设置参数默认值时,参数形成单独作用域,初始化结束后作用域消失。不设置参数默认值时无此行为。

let x = 1;
function f(y = x) { // 等同于 let y = x  let x = 2; console.log(y);
}
f() // 1

四、严格模式

函数参数使用默认值、解构赋值或扩展运算符时,函数内部不能显式设为严格模式,否则报错。

// 报错
function doSomething(a, b = a) {'use strict';// code
}// 报错
const doSomething = function ({a, b}) {'use strict';// code
};// 报错
const doSomething = (...a) => {'use strict';// code
};const obj = {// 报错doSomething({a, b}) {'use strict';// code}
};

五、箭头函数

  1. 定义方式:使用 “箭头”(=>)定义函数。
var f = v => v;
// 等同于
var f = function (v) {return v;
};var f = () => 5;
// 等同于
var f = function () { return 5 };var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {return num1 + num2;
};
  1. 代码块与返回值:代码块多于一条语句时,用大括号括起来并用return返回;返回对象需用括号包裹
var sum = (num1, num2) => { return num1 + num2; }
let getTempItem = id => ({ id: id, name: "Temp" });
  1. 注意点
    • 函数体内的this对象是定义时所在对象,非使用时所在对象。
    • 不可当作构造函数,不能用new命令,否则报错。
    • 不可使用arguments对象,可用 rest 参数代替。
    • 不可使用yield命令,不能用作 Generator 函数。

 

你是怎么理解ES6新增Set、Map两种数据结构的?

Set 数据结构

  • 集合
    是由一堆无序的、相关联的,且不重复的内存结构【数学中称为元素】组成的组合

  • 定义与特性:Set 是一种集合数据结构,类似于数组,但成员值唯一,无重复值。它以 [值, 值] 的形式存储元素。作为构造函数 new Set() 可生成 Set 结构。
  • 增删改查操作
    • add(value):添加值,若值已存在则不处理,返回 Set 本身,支持链式调用,如 s.add(1).add(2).add(2)
    • delete(value):删除值,返回布尔值表示删除是否成功,例如 s.delete(1)
    • has(value):判断值是否为成员,返回布尔值,如 s.has(2)
    • clear():清除所有成员,无返回值,即 s.clear()
  • 遍历方式
    • keys():返回键名遍历器(Set 中键名与键值相同)。
    • values():返回键值遍历器。
    • entries():返回键值对遍历器,每个键值对的键和值相同。
    • forEach()forEach()用于对每个成员执行某种操作,没有返回值,键值、键名都相等,同样的forEach方法有第二个参数,用于绑定处理函数的this。
      let set = new Set([1, 4, 9]);
      set.forEach((value, key) => console.log(key + ' : ' + value))
      // 1 : 1
      // 4 : 4
      // 9 : 9
  • 应用场景
    • 去重:结合扩展运算符可实现数组或字符串去重。如 let arr = [3, 5, 2, 2, 5, 5]; let unique = [...new Set(arr)] 实现数组去重;let str = "352255"; let unique = [...new Set(str)].join("") 实现字符串去重。
    • 集合运算:实现并集、交集和差集运算。例如:
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]); 
// 交集
let intersect = new Set([...a].filter(x => b.has(x))); 
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x =>!b.has(x))); 

 

Map 数据结构

字典
是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各不相同

  • 定义与特性:Map 是键值对的有序列表,键和值可以是任意类型,以 [键, 值] 的形式存储元素。通过 new Map() 构造函数生成。
  • 增删改查操作
    • size:返回成员总数,如 const map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2
    • set(key, value):设置键值对,若键已存在则更新值,返回 Map 本身,支持链式操作,例如 m.set(1, 'a').set(2, 'b').set(3, 'c')
    • get(key)读取键对应的值,若键不存在返回 undefined,如 m.get(hello)
    • has(key):判断键是否存在,返回布尔值,例如 m.has('edition')
    • delete(key):删除键,返回布尔值表示删除是否成功,如 m.delete(undefined)
    • clear():清除所有成员,无返回值,即 map.clear()
  • 遍历方式
    • keys():返回键名遍历器。
    • values():返回键值遍历器。
    • entries():返回所有成员的遍历器。
    • forEach(callback[, thisArg]):遍历 Map 所有成员,通过回调函数处理每个成员,可绑定 this
  • 应用场景:当需要存储键值对且键可以为任意类型时适用,比如在复杂数据关联场景中,键为对象、函数等类型的情况。

WeakSet 和 WeakMap

  • WeakSet
    • 特性:成员只能是引用类型,不支持遍历操作 API 且没有 size 属性。WeakSet 对成员的引用为弱引用,当外部对成员的引用消失,WeakSet 内的引用自动消失。
    • 创建与使用:可接受具有 Iterable 接口的对象作为参数,如 const a = [[1, 2], [3, 4]]; const ws = new WeakSet(a)
  • WeakMap
    • 特性:键名只能是对象(null 除外),不支持遍历操作 API 且没有 clear 方法。键名对对象的引用为弱引用,当键名所指向对象不再需要,相关键值对自动消失,但键值是正常引用。
    • 创建与使用:例如 const wm1 = new WeakMap(); const key = {foo: 1}; wm1.set(key, 2); wm1.get(key) // 2;也可接受数组作为构造函数参数 const k1 = [1, 2, 3]; const k2 = [4, 5, 6]; const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]); wm2.get(k2) // "bar"。常用于在 DOM 元素上添加数据,当 DOM 元素被清除,WeakMap 记录自动移除。

总之,Set 和 Map 及其变体 WeakSet 和 WeakMap 为 JavaScript 开发者提供了更灵活、高效处理数据集合与键值对存储的能力,在不同场景下能优化代码逻辑与性能。

 

你是怎么理解ES6中 Promise的?使用场景?

一、Promise 基本概念

  1. 定义与优势
    • Promise 是 ES6 为异步编程提供的解决方案,它比传统的回调函数方式更合理、强大。传统的多层异步操作使用回调函数容易形成回调地狱,代码可读性和维护性差。例如:
// 回调地狱示例
doSomething(function(result) {doSomethingElse(result, function(newResult) {doThirdThing(newResult, function(finalResult) {console.log('得到最终结果:'+ finalResult);}, failureCallback);}, failureCallback);
}, failureCallback);
  • 而使用 Promise 改写后,通过链式调用降低了编码难度,增强了代码可读性:
// Promise 链式调用示例
doSomething().then(function(result) {return doSomethingElse(result);
})
.then(function(newResult) {return doThirdThing(newResult);
})
.then(function(finalResult) {console.log('得到最终结果:'+ finalResult);
})
.catch(failureCallback);

状态

  • Promise 对象有三种状态:
    • pending(进行中):初始状态,异步操作正在执行。
    • fulfilled(已成功):异步操作成功完成。
    • rejected(已失败):异步操作失败。
  • Promise 对象状态具有以下特点:
    • 状态不受外界影响,仅由异步操作的结果决定。
    • 状态一旦改变(从 pending 变为 fulfilled 或从 pending 变为 rejected),就不会再变,任何时候都能获取到这个结果。

二、Promise 的用法

  1. 构造函数
    • Promise 是一个构造函数,用于生成 Promise 实例:
const promise = new Promise(function(resolve, reject) {});
  • 构造函数接受一个函数作为参数,该函数包含两个参数 resolve 和 reject
    • resolve 函数:将 Promise 对象的状态从 “未完成(pending)” 变为 “成功(fulfilled)”。
    • reject 函数:将 Promise 对象的状态从 “未完成(pending)” 变为 “失败(rejected)”。

 

  • 实例方法
    • then()
      • 用于指定状态改变时的回调函数,第一个参数是 resolved 状态的回调函数,第二个参数是 rejected 状态的回调函数。
      • then 方法返回一个新的 Promise 实例,这是 Promise 能链式书写的原因。例如:
getJSON("/posts.json").then(function(json) {return json.post;
}).then(function(post) {//...
});
  • catch()
    • catch() 方法是 .then(null, rejection) 或 .then(undefined, rejection) 的别名,用于指定发生错误时的回调函数。
    • Promise 对象的错误具有 “冒泡” 性质,会一直向后传递,直到被捕获为止。一般使用 catch 方法代替 then() 的第二个参数来处理错误。例如:
getJSON('/posts.json').then(function(posts) {//...
}).catch(function(error) {// 处理 getJSON 和前一个回调函数运行时发生的错误console.log('发生错误!', error);
});
  • finally()
    • finally() 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。例如:
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
  1. 构造函数方法
    • all()

      • Promise.all() 方法将多个 Promise 实例包装成一个新的 Promise 实例,接受一个数组(迭代对象)作为参数,数组成员都应为 Promise 实例。
        const p = Promise.all([p1, p2, p3]);
      • 新实例 p 的状态由传入的实例决定:
        • 只有当所有传入的 Promise 实例(如 p1p2p3)的状态都变成 fulfilledp 的状态才会变成 fulfilled,此时这些实例的返回值组成一个数组,传递给 p 的回调函数。
        • 只要有一个实例被 rejectedp 的状态就变成 rejected,此时第一个被 rejected 的实例的返回值,会传递给 p 的回调函数。
      • 注意,如果作为参数的 Promise 实例自己定义了 catch 方法,它被 rejected 时,不会触发 Promise.all() 的 catch 方法。

      race()

      • Promise.race() 方法同样将多个 Promise 实例包装成一个新的 Promise 实例。
      • 只要其中有一个实例率先改变状态,新 Promise 的状态就跟着改变,且率先改变状态的 Promise 实例的返回值传递给新 Promise 的回调函数。例如:
const p = Promise.race([fetch('/resource - that - may - take - a - while'),new Promise(function(resolve, reject) {setTimeout(() => reject(new Error('request timeout')), 5000)})
]);
p
.then(console.log)
.catch(console.error);
  • allSettled()

    • Promise.allSettled() 方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。
    • 只有等到所有参数实例都返回结果(无论是 fulfilled 还是 rejected),包装实例才会结束。例如:
const promises = [fetch('/api - 1'),fetch('/api - 2'),fetch('/api - 3')
];
await Promise.allSettled(promises);
removeLoadingIndicator();
  • resolve()

    • 将现有对象转为 Promise 对象。参数情况如下:
      • 参数是一个 Promise 实例,Promise.resolve 将不做任何修改、原封不动地返回这个实例。
      • 参数是一个 thenable 对象(具有 then 方法的对象),Promise.resolve 会将这个对象转为 Promise 对象,然后立即执行 thenable 对象的 then() 方法。
      • 参数不是具有 then() 方法的对象,或根本就不是对象,Promise.resolve() 会返回一个新的 Promise 对象,状态为 resolved
      • 没有参数时,直接返回一个 resolved 状态的 Promise 对象。
  • reject()

    • Promise.reject(reason) 方法返回一个新的 Promise 实例,该实例的状态为 rejected。例如:
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'));
p.then(null, function(s) {console.log(s);
});
// 出错了
  • Promise.reject() 方法的参数,会原封不动地变成后续方法的参数。

三、Promise 的使用场景

  1. 图片加载:可以将图片加载操作封装成 Promise,当图片加载完成(成功或失败)时,Promise 状态相应改变,便于后续处理。例如:
const preloadImage = function(path) {return new Promise(function(resolve, reject) {const image = new Image();image.onload = resolve;image.onerror = reject;image.src = path;});
};
  1. 链式异步操作:通过链式操作,将多个渲染数据分别交给不同的 then 处理,各司其职;当下个异步请求依赖上个请求结果时,也能通过链式操作友好解决。例如:
// 各司其职示例
getInfo().then(res => {let { bannerList } = res;// 渲染轮播图console.log(bannerList);return res;
}).then(res => {let { storeList } = res;// 渲染店铺列表console.log(storeList);return res;
}).then(res => {let { categoryList } = res;console.log(categoryList);// 渲染分类列表return res;
});
  1. 多个请求合并:使用 Promise.all() 实现多个请求合并,汇总所有请求结果,只需设置一个加载指示器(如 loading)。例如:
function initLoad() {// loading.show(); // 加载loadingPromise.all([getBannerList(), getStoreList(), getCategoryList()]).then(res => {console.log(res);loading.hide(); // 关闭loading}).catch(err => {console.log(err);loading.hide();// 关闭loading});
}
// 数据初始化
initLoad();
  1. 设置请求超时:利用 Promise.race() 可以设置图片请求等操作的超时。例如:
// 请求某个图片资源
function requestImg() {var p = new Promise(function(resolve, reject) {var img = new Image();img.onload = function() {resolve(img);};// img.src = "https://b - gold - cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的img.src = "https://b - gold - cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";});return p;
}// 延时函数,用于给请求计时
function timeout() {var p = new Promise(function(resolve, reject) {setTimeout(function() {reject('图片请求超时');}, 5000);});return p;
}Promise
.race([requestImg(), timeout()])
.then(function(results) {console.log(results);
})
.catch(function(reason) {console.log(reason);
});

 

http://www.dtcms.com/a/395268.html

相关文章:

  • npm和pnpm命令大全
  • kali下安装beef-xss报错-启动失败-简单详细
  • 政策法规下的LLM安全:合规之路
  • 《第21课——C typedef:从Java的“实名制”到C的“马甲生成器”——类型伪装术与代码整容的艺术》
  • 【每天一个知识点】什么是知识库?
  • 豆包·Seedream 4.0深度测评:4K多模态时代的图像创作革命(图文增强版)
  • [新启航]发动机喷管推进剂输送孔光学 3D 轮廓测量 - 激光频率梳 3D 轮廓技术
  • 深入理解 TCP 协议:三次握手与四次挥手的底层原理
  • PyTorch 神经网络工具箱
  • 机器学习-多因子线性回归
  • 国产化Excel开发组件Spire.XLS教程:Python 写入 Excel 文件,数据写入自动化实用指南
  • 08 - spring security基于jdbc的账号密码
  • 解决SSL证书导致源站IP被泄露的问题
  • Worst Western Hotel: 1靶场渗透
  • 电子电气架构 --- 软件开发与产品系统集成流程(上)
  • 运维安全08,日志检测和 tcpdump (抓包) 的介绍以及使用
  • DSC 归档配置相关
  • 彭博社-BloombergGPT金融大模型
  • GPT5 Codex简单快速上手
  • Linux配置白名单限制访问_ipset+iptables
  • 多元化通证经济模型:DAO的神经和血液
  • 高系分十六:web应用
  • 【LeetCode热题100(27/100)】合并两个有序链表
  • 嵌入式(SOC+FreeRTOS)汽车仪表盘接口参数安全:规范遵循与防护实践
  • Maven 完整教程
  • 数据驱动下的用户画像系统:从0到1的技术实战与避坑指南
  • 同一个灰色,POI取出来却是白色:一次Excel颜色解析的踩坑记录
  • Excel——常用函数一
  • 立项依据不足会给项目带来哪些风险
  • 从 0 到 1 精通 SkyWalking:分布式系统的 “透视镜“ 技术全解析