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

news/2024/10/16 16:08:36 标签: es6, 前端, ecmascript

目录

一、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语句来实现。

http://www.niftyadmin.cn/n/5708190.html

相关文章

【LeetCode】每日一题 2024_10_9 找到按位或最接近 K 的子数组(LogTrick、位运算)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;找到按位或最接近 K 的子数组 代码与解题思路 今天是 2100 的题目&#xff0c;难度略高&#xff0c;不在我的能力范围&#xff0c;推荐题解&#xff1a;两种方法&#xff1a;LogTrick/滑…

Prism导航入门学习笔记

首先创建一个空的Prism项目 在View文件夹中创建一个UserControl的A界面&#xff0c;再在ViewModel中创建一个AViewModel的类 在主页面中创建Button按钮&#xff0c;使用Command属性&#xff0c;指向导航命令的方法&#xff0c;CommandParameter指向导航的页面 <Grid><…

Go语言基础学习(Go安装配置、基础语法)

一、简介及安装教程 1、为什么学习Go&#xff1f; 简单好记的关键词和语法&#xff1b;更高的效率&#xff1b;生态强大&#xff1b;语法检查严格&#xff0c;安全性高&#xff1b;严格的依赖管理&#xff0c; go mod 命令&#xff1b;强大的编译检查、严格的编码规范和完整的…

C++学习路线(十六)

void类型指针 void -> 空类型 void* -> 空类型指针&#xff0c;只存储地址的值&#xff0c;丢失类型&#xff0c;无法访问&#xff0c;要访问里面的值 我们必须对指针进行正确的类型转换&#xff0c;然后再间接引用指针 所有其它类型的指针都可以隐式自动转换成 void 类型…

高级算法设计与分析 学习笔记13 线性规划

注意是线性规划不是动态规划哦 好家伙&#xff0c;这不是凸优化吗&#xff1f; 凸优化标准形式&#xff1a; 先改成统一最大化&#xff08;凸优化那边怎么是统一最小化&#xff1f;&#xff09; 原来的x2正负无所谓&#xff0c;但我希望每个x都是有限制的&#xff0c;所以把它改…

【整合包及教程】第二代GPT-SoVITS V2:革新声音克隆技术

随着人工智能技术的飞速发展&#xff0c;语音克隆技术也在不断进化。近期推出的第二代GPT-SoVITS V2&#xff0c;以其强大的功能和易用性&#xff0c;成为该领域的一大突破。GPT-SoVITS V2不仅能够基于少量的语音样本&#xff08;例如1分钟的音频&#xff09;来克隆音色&#x…

深入解析 Go 语言接口:多接口实现与接口组合的实际应用

文章目录 一、引言二、一个类型实现多个接口1. 定义多个接口2. 类型实现多个接口3. 使用多个接口 三、接口的组合1. 接口嵌套2. 实现复合接口 四、实际开发中的应用场景1. 多态与模块化设计2. 松耦合系统设计3. 测试与依赖注入4. 事件驱动架构中的应用 五、小结 一、引言 在 G…

【修订中】ffmpeg 知识点

一、两种安装方式 static FFmpeg binaries for macOS 64-bit Intel brew install ffmpeg 时间有点长 需要挂上代理 二、ffmpeg 使用这个工具去除水印以后原来水印的那个点就模糊了如何解决这个问题呢 使用 FFmpeg 的delogo过滤器去除水印时&#xff0c;通常会导致水印所…