欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > ES6新特性2- Promise的介绍和使用,map和set集合,ES6-新增对象方法, async和await

ES6新特性2- Promise的介绍和使用,map和set集合,ES6-新增对象方法, async和await

2024/10/23 8:54:52 来源:https://blog.csdn.net/m0_64450406/article/details/142721674  浏览:    关键词:ES6新特性2- Promise的介绍和使用,map和set集合,ES6-新增对象方法, async和await

目录

一、Promise简介

二、Promise的三种状态

三、Promise的基本用法

四、Promise的实例方法

五、Promise的链式调用

 六、Promise封装读取文件

步骤

七、promise封装AJAX请求

map和set()

map()

Set

拓展

注意

ES6-新增对象方法

1. Object.is()

2. Object.assign()

3. Object.getOwnPropertyDescriptors()

4. Object.setPrototypeOf() 和 Object.getPrototypeOf()

5. Object.keys()、Object.values() 和 Object.entries()

6. Object.fromEntries()

 async和await

一、async

二、await

三、使用示例

四、注意事项


一、Promise简介

Promise是ES6(ECMAScript 2015)引入的一个重要特性,它是异步编程的一种解决方案。在Promise出现之前,JavaScript的异步操作大多依赖于回调函数,但随着异步操作的复杂度增加,回调函数会出现“回调地狱”的问题,即过度使用嵌套回调函数导致代码的可读性和维护性变差。Promise的出现解决了这一问题,它提供了一种更优雅、更清晰的异步编程方式。

二、Promise的三种状态

Promise对象有三种状态:

  1. Pending(进行中):Promise对象初始状态,既没有被兑现(fulfilled),也没有被拒绝(rejected)。
  2. Fulfilled(已成功):意味着操作成功完成。
  3. Rejected(已失败):意味着操作失败。

Promise的状态只能从Pending变为Fulfilled或Rejected,且状态一旦改变,就不可逆转。

三、Promise的基本用法
  1. 创建Promise对象
const promise = new Promise((resolve, reject) => { 
// 异步操作 
if (/* 异步操作成功 */) { 
resolve(value); // 将Promise对象的状态从Pending变为Fulfilled 
} else { 
reject(error); // 将Promise对象的状态从Pending变为Rejected 
} 
});
  1. 使用Promise对象

Promise对象提供了.then().catch().finally()方法用于处理异步操作的结果或错误。

  • .then()方法接受两个可选的回调函数作为参数,第一个回调函数在Promise对象的状态变为Fulfilled时调用,第二个回调函数在Promise对象的状态变为Rejected时调用。
  • .catch()方法是.then(null, rejectionHandler)的简写形式,专门用于捕获前面链中任何.then()的错误。
  • .finally()方法无论Promise最后的状态如何,都会执行提供的回调函数,常用于资源清理或UI恢复等场景。
四、Promise的实例方法
  1. .then()
promise.then( 
function(value) { 
// 处理Fulfilled状态 
}, 
function(error) { 
// 处理Rejected状态 
} 
);
  1. .catch()
promise.catch(function(error) { // 处理错误 });
  1. .finally()
promise.finally(function() { 
// 不管Promise最终是fulfilled还是rejected都会执行的代码 
});

五、Promise的构造函数方法

  1. Promise.all()

Promise.all()方法接受一个Promise数组作为参数,当所有Promise都变为Fulfilled时,返回一个包含所有结果的数组;当任意一个Promise变为Rejected时,立即返回该Promise的错误信息。

Promise.all([promise1, promise2, promise3]) .then(function(values) { // 处理成功 }) .catch(function(error) { // 处理失败 });
  1. Promise.race()

Promise.race()方法与Promise.all()类似,也接受一个Promise数组作为参数,但是只要有一个Promise变为Fulfilled或Rejected时,立即返回该Promise的结果或错误信息。

Promise.race([promise1, promise2, promise3]) .then(function(value) { // 处理成功 }) .catch(function(error) { // 处理失败 });
  1. Promise.allSettled()

Promise.allSettled()方法也接受一个Promise数组作为参数,当所有Promise都被resolved时(无论是fulfilled还是rejected),返回一个包含所有结果的数组(每个结果包括状态和值)。

Promise.allSettled([promise1, promise2, promise3]) 
.then(function(results) { 
// 处理成功 
}) 
.catch(function(error) { 
// 处理失败(注意:Promise.allSettled()本身不会rejected,因此这里的catch通常不会执行) 
});
  1. Promise.resolve() 和 Promise.reject()
  • Promise.resolve():创建并返回一个已经resolved的Promise,通常用于将非Promise值转换为Promise,或者快速返回一个成功的Promise。
  • Promise.reject():创建并返回一个已经被rejected的Promise,用于快速抛出错误。
五、Promise的链式调用

Promise支持链式调用,可以使用.then()方法将多个异步操作串起来执行。每个.then()方法返回一个新的Promise对象,因此可以继续调用.then()方法进行下一步操作。

promise 
.then(function(result1) { 
return result2; // 或者返回另一个Promise对象 
}) 
.then(function(result2) { 
return result3; 
}) 
.catch(function(error) { 
// 处理错误 
}) 
.finally(function() { 
// 清理资源或恢复UI 
});
 六、Promise封装读取文件
const fs = require('fs').promises;  // 定义一个异步函数来读取文件  
async function readFileAsync(filePath) {  try {  const data = await fs.readFile(filePath, 'utf8');  console.log('文件内容:', data);  } catch (error) {  console.error('读取文件时出错:', error);  }  
}  // 调用函数并传入文件路径  
const filePath = './example.txt';  
readFileAsync(filePath);
步骤

引入fs.promises

const fs = require('fs').promises;
fs.promises 提供了一组返回Promise的方法,用于文件系统操作。

定义异步函数readFileAsync:

async function readFileAsync(filePath) {

读取文件:

const data = await fs.readFile(filePath, 'utf8');
//使用await关键字等待fs.readFile方法返回的Promise解决,并将文件内容存储在data变量中。第二个参数'utf8'指定了文件的编码格式。

处理文件内容或错误:

console.log('文件内容:', data);
//如果文件读取成功,将文件内容打印到控制台。
} catch (error) {  console.error('读取文件时出错:', error);  
}
//如果文件读取失败,捕获错误并打印到控制台。

调用函数:

const filePath = './example.txt';  
readFileAsync(filePath);
//调用readFileAsync函数并传入文件路径
七、promise封装AJAX请求
// 定义一个函数,该函数返回一个Promise对象  
function ajaxRequest(url, method = 'GET', data = null) {  return new Promise((resolve, reject) => {  // 创建一个XMLHttpRequest对象  const xhr = new XMLHttpRequest();  // 初始化请求  xhr.open(method, url, true);  // 设置请求头(如果需要)  // xhr.setRequestHeader('Content-Type', 'application/json');  // 处理请求完成后的响应  xhr.onload = () => {  if (xhr.status >= 200 && xhr.status < 300) {  // 请求成功,解析并返回响应数据  try {  const response = JSON.parse(xhr.responseText);  resolve(response);  } catch (error) {  reject(new Error('Error parsing JSON response'));  }  } else {  // 请求失败,返回错误信息  reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`));  }  };  // 处理网络错误  xhr.onerror = () => {  reject(new Error('Network Error'));  };  // 发送请求(如果是POST请求,则传递数据)  if (method === 'POST' && data !== null) {  xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');  xhr.send(JSON.stringify(data));  } else {  xhr.send();  }  });  
}  // 使用示例  
ajaxRequest('https://api.example.com/data')  .then(response => {  console.log('Success:', response);  })  .catch(error => {  console.error('Error:', error.message);  });  // 发送POST请求的示例  
const postData = { key: 'value' };  
ajaxRequest('https://api.example.com/submit', 'POST', postData)  .then(response => {  console.log('POST Success:', response);  })  .catch(error => {  console.error('POST Error:', error.message);  });

定义函数ajaxRequest:
该函数接收三个参数:url(请求的URL),method(请求方法,默认为GET),data(请求数据,默认为null)。
返回一个Promise对象。
创建XMLHttpRequest对象:
使用new XMLHttpRequest()创建一个新的请求对象。
初始化请求:
使用xhr.open(method, url, true)初始化请求。
设置请求头:
如果需要发送JSON数据,可以添加Content-Type头。
处理响应:
使用xhr.onload处理请求完成后的响应。
如果响应状态码在200到299之间,则解析JSON数据并调用resolve。
如果响应状态码不在此范围内,则调用reject。
处理网络错误:
使用xhr.onerror处理网络错误。
发送请求:
根据请求方法(GET或POST)调用xhr.send()发送请求。
如果是POST请求,则将数据转换为JSON字符串并发送。
使用示例:

// 发送POST请求的示例  
const postData = { key: 'value' };  
ajaxRequest('https://api.example.com/submit', 'POST', postData)  .then(response => {  console.log('POST Success:', response);  })  .catch(error => {  console.error('POST Error:', error.message);  });

map和set()

map()

map()对象用于保存键值对,任何JS支持的值都可以作为一个键(key)或者是一个value()

与对象的不同之处:

  1. Object()的键只能是字符串或是ES6的symbol(),而map()可以是任何值
  2. Map 提供了 get()、set()、has()、delete() 和 clear() 等方法
  3. map对象有一个size属性可以获取map的大小(即键值对的个数)
// 使用字符串字面量作为键  
var map1 = new Map([['name', 'ren'], ['age', 18]]);  
// 添加一个新的键值对到 Map 中  
// 注意:'score' 也应该是一个字符串字面量,除非您之前已经声明了变量 score  
map1.set('score', 85);  
console.log(map1); // 输出 Map(3) { 'name' => 'aille', 'age' => 18, 'score' => 85 } 或类似格式  
// 从 Map 中删除一个键值对  
map1.delete('age');  
// 检查 Map 中是否包含某个键  
console.log(map1.has('score')); // 输出 true  
// 获取 Map 中与某个键关联的值  
console.log(map1.get('score')); // 输出 85  
// 获取 Map 的大小  
console.log(map1.size); // 输出 2  
// 清空 Map  
map1.clear();  
console.log(map1.size); // 输出 0  
Set

Set 是一种集合数据结构,它允许你存储任何类型的唯一值(即没有重复的值)。Set 对象是值的集合,其中的值都是唯一的,没有重复的值 。

  • Map 提供了 add()、has()、delete() 和 clear() 等方法和size属性

// 创建一个新的 Set  
const set1 = new Set([1, 2, 3, 4, 5]);  
// 向 Set 中添加一个元素  p
console.log(set1); 
//向set()中添加一个元素
console.log(set1.add(6));
// 检查 Set 中是否包含某个元素  
console.log(set1.has(1)); // true  
// 从 Set 中删除一个元素  
console.log(set1.delete(5));
// 清空 Set  
set1.clear();  
console.log(set1.size); // 输出 0   
拓展

1.利用set可以进行数组去重结合扩展运算符和Array.form()方法

//set(数组去重)  
const arr = [1, 2, 3, 4, 5, 5, 6, 7,7, 8, 9, 10];  
const set2 = new Set(arr);  
//把set转换为数组  
const arr2 = [...set2];  console.log(arr2); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]const arr3=Array.from(set2);  console.log(arr3); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

2.交集,利用数组方法filter()和set.has方法结合

//交集  
const set3 = new Set([1, 2, 3]);  
const set4 = new Set([2, 3, 4]);  const intersection = new Set([...set3].filter(value => set4.has(value)));  console.log(intersection); // Set(2) { 2, 3 }  

3.并集

 //并集  const union = new Set([...set3,...set4]);  console.log(union); // Set(4) { 1, 2, 3, 4 }  

4.差集

//差集  const difference = new Set([...set3].filter(value => !set4.has(value)));  console.log(difference); // Set(1) { 1 }  
注意
  • Set 中的值都是唯一的,不会有重复的值。
  • Map 允许使用任何类型作为键(包括对象),而对象的键只能是字符串(或者 Symbol)。
  • 当你使用 for...of 循环遍历 Set 或 Map 时,Set 返回的是值,而 Map 返回的是键值对(即 [key, value] 数组)。

ES6-新增对象方法

1. Object.is()

目的:用来比较两个值是否严格相等。
用法:与严格比较符(===)的行为基本一致,但有两个不同之处:+0不等于-0,NaN等于自身。
示例:

console.log(Object.is(+0, -0)); // false  
console.log(Object.is(NaN, NaN)); // true
2. Object.assign()

目的:用于将对象合并,将源对象可枚举的属性复制到目标对象。
用法:Object.assign(target, ...sources)。第一个参数是目标对象,后面的参数都是源对象。若目标和源有同名属性,或多个源有同名属性,后面的属性会覆盖前面的属性。该方法只考虑对象自身属性,不考虑继承的属性。
示例:

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

注意:该方法实行的是浅拷贝。

3. Object.getOwnPropertyDescriptors()

目的:用于获取指定对象所有自身属性(非继承属性)的描述对象,解决Object.assign()无法正确拷贝get和set属性的问题。
用法:Object.getOwnPropertyDescriptors(obj)。
示例:

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

用途:与Object.defineProperties()方法配合,用于对象拷贝。

4. Object.setPrototypeOf() 和 Object.getPrototypeOf()

Object.setPrototypeOf():设置一个对象的原型。
用法:Object.setPrototypeOf(obj, proto)。
示例:

let proto = {};  
let obj = { x: 10 };  
Object.setPrototypeOf(obj, proto);  
proto.y = 20;  
console.log(obj.y); // 20
Object.getPrototypeOf():读取一个对象的原型。

用法:Object.getPrototypeOf(obj)。

5. Object.keys()、Object.values() 和 Object.entries()
  • Object.keys():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
  • Object.values():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
  • Object.entries():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

示例:

const obj = { foo: 'bar', baz: 42 };  
console.log(Object.keys(obj)); // ["foo", "baz"]  
console.log(Object.values(obj)); // ["bar", 42]  
console.log(Object.entries(obj)); // [["foo", "bar"], ["baz", 42]]
6. Object.fromEntries()

目的:Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。
用法:Object.fromEntries(entries)。
示例:

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

 async和await

async和await是ES2016(ES7)中新增的两个关键字,它们旨在简化Promise API的使用,使异步代码看起来和表现起来更像同步代码。

一、async

定义:async是一个修饰符,用于修饰函数(无论是函数字面量还是函数表达式),放置在函数最开始的位置。被async修饰的函数的返回结果一定是Promise对象。
作用:

  1. 将不是Promise对象的返回值封装为resolved的Promise并返回。
  2. 如果没有返回值,则返回一个rejected的Promise。
  3. 使得对async函数的调用不会造成阻塞,其内部所有的阻塞都被封装在一个Promise对象中异步执行。
二、await

定义:await也是一个修饰符,但只能放在async函数内部。
作用:

  1. 等待一个Promise对象返回的结果。如果等待的不是Promise对象,则返回该值本身。
  2. 阻塞当前async函数的执行,直到等待的Promise对象被resolve或reject。注意,这里的“阻塞”并不会花费CPU资源,因为JavaScript引擎能够同时做其他工作,如执行其他脚本、处理事件等。
  3. 使得异步代码可以按照同步代码的方式书写和阅读,从而提高了代码的可读性和可维护性。
三、使用示例
function takeLongTime(n) {  return new Promise(resolve => {  setTimeout(() => resolve(n + 200), n);  });  
}  async function work() {  console.time('work');  const time1 = await takeLongTime(300);  const time2 = await takeLongTime(time1);  const time3 = await takeLongTime(time2);  console.log(`你最终挣了${time3}`);  console.timeEnd('work');  
}  work();
四、注意事项
  • await只能用在async函数中。
  • 如果await等待的是一个非Promise对象,它会直接返回该值,而不会造成阻塞。
  • 使用async和await时,需要处理可能发生的异常。这可以通过在async函数中使用try...catch语句来实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com