前端技巧第七期JavaScript异步

关于JavaScript 异步方案 async/await 从代码片段中不难看出 Promise 没有解决好的事情,比如要有很多的 then 方法,整块代码会充满 Promise 的方法,而不是业务逻辑本身,而且每一个 then 方法内部是一个独立的作用域,要是想共享数据,就要将部分数据暴露在最外层,在 then 内部赋值一次。虽然如此,Promise 对于异步操作的封装还是非常不错的,所以 async/await 是基于 Promise 的,await 后面是要接收一个 Promise 实例。服务端使用 Babel,最简单的方式是通过 require hook。 阅读详情

异步核心概念

优点
避免阻塞:JavaScript是单线程语言,异步操作可防止长时间任务阻塞主线程
提升性能:充分利用I/O等待时间处理其他任务
响应式体验:保持UI流畅响应,特别是在浏览器环境中
事件循环机制
// 演示事件循环执行顺序
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
/* 输出顺序:
Start
End
Promise
Timeout
*/
执行上下文
调用栈(Call Stack):同步代码执行容器
任务队列(Task Queue):存放宏任务(setTimeout、I/O)
微任务队列(Microtask Queue):存放微任务(Promise、MutationObserver)

异步编程演进史

回调函数(Callback)
 function fetchData(callback) {
    setTimeout(() => {
       callback('Data received');
   }, 1000);
}
fetchData((data) => {
            // 1秒后输出
            console.log(data);
});
回调函数存在的问题:回调地狱(Callback Hell)
getUser(userId, (user) => {
    getOrders(user.id, (orders) => {
         getProducts(orders[0].id, (products) => {
            renderPage(user, orders, products);
         });
    });
});
Promise(ES6)
        const promiseExample = new Promise((resolve, reject) => {
            setTimeout(() => {
                Math.random() > 0.5 ? resolve('Success!') : reject(new Error('Failed'));
            }, 1000);
        });
        promiseExample
            .then(console.log)
            .catch(console.error);
async/await(ES2017)
        async function fetchUser() {
            try {
                const response = await fetch('/api/user');
                const data = await response.json();
                return data;
            } catch (error) {
                console.error('Fetch failed:', error);
            }
        }

Promise 深度解析

状态管理
Pending(进行中)  
Fulfilled(已成功)  
Rejected(已失败)
链式调用
        checkInventory()
            .then((stock) => placeOrder(stock))
            .then((order) => processPayment(order))
            .then((receipt) => sendConfirmation(receipt))
            .catch(handleErrors);
组合方法
  		// 并行执行
        Promise.all([api1, api2, api3])
            .then(([res1, res2, res3]) => {/* ... */ });
        // 竞速模式
        Promise.race([fastAPI, slowAPI])
        .then(firstResult => { /* ... */ });
        // 全成功或全部失败
        Promise.allSettled([req1, req2])
        .then(results => { /* ... */ });

async/await最佳实践

错误处理模式
        // 方法1:try/catch
        async function safeFetch() {
            try {
                const res = await fetch(url);
                return await res.json();
            } catch (err) {
                console.error('Request failed:', err);
                return null;
            }
        }
        // 方法2:高阶函数封装
        const asyncHandler = (promise) =>
            promise.then(data => [null, data])
                .catch(err => [err, null]);
并行优化
        // 顺序执行(低效)
        const user = await getUser();
        const orders = await getOrders(user.id);
        // 并行执行(推荐)
        const [user, orders] = await Promise.all([
            getUser(),
            getOrders(userId)
        ]);
循环中的异步
        // 错误方式(forEach不等待)
        array.forEach(async item => {
            await process(item);
        });
        // 正确方式
        for (const item of array) {
            await process(item); // 顺序执行
        }
        // 并行方式
        await Promise.all(array.map(item => process(item)));

高级异步模式

发布订阅模式
        class EventEmitter {
            constructor() {
                this.events = {};
            }
            on(event, listener) {
                (this.events[event] || (this.events[event] = [])).push(listener);
            }
            emit(event, ...args) {
                (this.events[event] || []).forEach(listener => listener(...args));
            }
        }
Web Workers
        // main.js
        const worker = new Worker('worker.js');
        worker.postMessage({
            type: 'CALC', data: bigArray
        });
        worker.onmessage = (e) => {
            console.log('Result:', e.data);
        };
        // worker.js
        self.onmessage = function (e) {
            if (e.data.type === 'CALC') {
                const result = heavyCalculation(e.data.data);
                self.postMessage(result);
            }
        };

错误处理策略

全局错误捕获
		// 浏览器环境
        window.addEventListener('unhandledrejection', (event) => {
            console.error('Unhandled rejection:', event.reason);
        });
        // Node.js环境
        process.on('unhandledRejection', (reason, promise) => {
            console.error('Unhandled Rejection at:', promise, 'reason:', reason);
        });
重试机制
        async function retry(fn, retries = 3, delay = 1000) {
            try {
                return await fn();
            } catch (err) {
                if (retries <= 0) throw err;
                await new Promise(res => setTimeout(res, delay));
                return retry(fn, retries - 1, delay * 2);
            }
        }

性能优化

节流防抖
        // 防抖实现
        function debounce(fn, delay) {
            let timer;
            return (...args) => {
                clearTimeout(timer);
                timer = setTimeout(() => fn(...args), delay);
            };
        }
        // 节流实现
        function throttle(fn, interval) {
            let lastTime = 0;
            return (...args) => {
                const now = Date.now();
                if (now - lastTime >= interval) {
                    fn(...args); lastTime = now;
                }
            };
        }
请求缓存
        const apiCache = new Map();
        async function cachedFetch(url) {
            if (apiCache.has(url)) {
                return apiCache.get(url);
            }
            const response = await fetch(url);
            const data = await response.json();
            apiCache.set(url, data); return data;
        }

开发场景


        async function loadPageData() {
            const [user, posts] = await Promise.all([fetch('/api/user'), fetch('/api/posts')]);
            return { user: await user.json(), posts: await posts.json() };
        }

文件上传处理

        async function uploadFiles(files) {
            const uploadPromises = files.map(file => {
                const formData = new FormData(); formData.append('file', file);
                return fetch('/upload', { method: 'POST', body: formData });
            });
            const results = await Promise.allSettled(uploadPromises);  // 处理上传结果
        }

结语

 1.优先使用async/await:提升代码可读性    
 2.避免过度并行:控制并发数量(使用p-limit等库)    
 3.及时清理资源:取消不必要的请求(AbortController)    
 4.监控异步性能:使用Performance API进行分析    
 5.保持错误可追踪:附加上下文错误信息
        // 使用AbortController取消请求
        const controller = new AbortController();
        fetch(url, {
            signal: controller.signal
        }).then(/* ... */).catch(err => {
            if (err.name === 'AbortError') {
                console.log('Request aborted');
            }
        });
        // 取消请求
        controller.abort();
前端开发者必看:Node.js实战技巧大揭秘 本文章的目的在于为前端开发者提供全面且深入的Node.js实战技巧。通过对Node.js核心知识的讲解、实际案例的分析以及相关资源的推荐,帮助前端开发者能够熟练运用Node.js进行前端项目的开发、优化和部署。文章范围涵盖了Node.js的基础概念、核心算法、项目实战、应用场景以及未来发展等多个方面。本文将按照以下结构进行组织:首先介绍Node.js的背景和相关术语,然后讲解Node.js的核心概念与联系,接着阐述核心算法原理和具体操作步骤,通过数学模型和公式加深理解。 阅读详情

相关推荐

西门子CPU与汇川伺服通信与控制

第三方驱动器的配置内容和西门子的配置内容基本一致,基本上会一种即可知道其他品牌的配置默认报文,需要激活硬限位才能收到限位信号默认报文,原点信号不能实时输出到PLC;自定义报文,需要伺服端设置DIN点位。

大小曲奇的博客 1万+

一天时间迅速准备前端面试|JavaScript——异步进阶

JS 的特色就是异步编程,所有有很多关于异步的考点,本章都会讲解。如 event loop、promise、async-await、微任务和宏任务。学不会这些,就不算是精通 JS。

江拥羡橙的博客 1193

SCAN和JTAG分别是什么?它们之间有什么联系与区别?

SCAN(扫描)技术是集成电路测试领域的一种方法,主要用于边界扫描测试(Boundary Scan)。它是在集成电路设计中引入的一种测试结构,允许测试人员通过在芯片的输入/输出引脚上设置和读取特殊寄存器(边界扫描寄存器,BSR)的内容,来间接测试电路板上的互联和芯片内部功能块。这种方式可以在不接触其他内部节点的情况下测试整个电路板的连接性,极大地提高了测试覆盖率和可诊断性。JTAG(Joint Test Action Group,联合测试行动小组)则是开发并推广边界扫描测试标准的一个组织。

初心不忘产学研的博客 2543

提升前端性能的JavaScript技巧

本文将深入探讨一系列提升前端性能的JavaScript技巧,涵盖代码优化、DOM操作、异步处理、缓存策略等多个方面,旨在帮助开发者构建更高效、更流畅的Web应用。然而,需要注意的是,每个项目的具体需求和场景不同,因此在实际应用中需要根据具体情况选择最合适的优化策略。现代浏览器(如Chrome、Firefox、Safari等)都提供了强大的开发者工具,包括性能分析器(Performance Profiler)、网络分析器(Network Analyzer)等,可以帮助开发者监测和分析前端性能问题。

jun778895的博客 908

一文帮你彻底搞懂ARM Debug Interface之SWD(转)

ARM的文档写的已经很好了,但是关于上电以后的第一时间应该怎么操作,依然写的不够清晰,导致我第一次用的时候还是费了一些周折。今天做一个详细的梳理,希望能够帮助到更多的朋友。BTW, ARM_Cortex-M0/3 DesignStart系列会持续更新,只是中间可能会穿插其他知识点。SWD是Serial Wire Debug的简称,翻译成中文是”串行线调试”。

2302_79847220的博客 6861

保姆级教程:手把手调试PX4Ctrl的油门映射与姿态控制(附ROS节点配置)

本文提供PX4Ctrl的深度调参指南,涵盖油门映射、姿态控制及ROS节点配置等关键环节。通过详细解析PX4控制器的核心逻辑、递归最小二乘法(RLS)参数估计及状态机设计,帮助开发者优化无人机飞控性能。附实战案例与安全调试建议,适合PX4开发者进阶学习。

weixin_30363981的博客 382

Node.js和前端JavaScript有什么区别?

Node.js 和前端 JavaScript 在语法上基本相同,但它们的运行环境、用途、模块系统以及性能优化策略有着显著的区别。前端 JavaScript 专注于浏览器端的交互和界面逻辑,而 Node.js 扩展了 JavaScript 的应用范围,使其能够在服务器端运行,处理文件、网络和数据流等任务。了解这些区别对于选择合适的工具和策略来构建高效、可维护的应用程序至关重要。最后问候亲爱的朋友们,并邀请你们阅读我的全新著作书籍详情。

有我更精彩的博客 1508

2025ICPC南昌邀请赛题解

2025ICPC南昌邀请赛由XDU和WHU联合出题的ICPC南昌邀请赛,榜单显示8题金、6题银、5题铜。

weixin_50089904的博客 1960

前端JS基础面试技巧-- 异步和单线程

前端JS基础面试技巧 前端JS基础面试技巧 – JS基础知识下 JS 三座大山:原型原型链 、作用域闭包 、异步和单线程 。 3-1 异步和单线程 3-2 日期和math 日期 Math 数组 API 对象 API 3-1 异步和单线程 异步和单线程 题目 知识点 解答 题目 同步和异步的区别是什么?分别举一个同步和异步的例子 一个关于 setTimeout 的笔试题 前端使用异步...

周琛的点滴记录~ 422

C#联合Halcon机器视觉框架源码

本软件参考EV开发,共用模块,基于WPF+Halcon,是非常不错的学习框架,需要什么功能可以自己添加,插件式开发非常方便。

Z's Palace 4829

多智能体强化学习算法【三】【QMIX、MADDPG、MAPPO】

相关文章: 1.QMIX算法简述 QMIX是一个多智能体强化学习算法,具有如下特点: 1. 学习得到分布式策略。 2. 本质是一个值函数逼近算法。 3. 由于对一个联合动作-状态只有一个总奖励值,而不是每个智能体得到一个自己的奖励值,因此只能用于合作环境,而不能用于竞争对抗环境。 4. QMIX算法采用集中式学习,分布式执行应用的框架。通过集中式的信息学习,得到每个智能体的分布式策略。 5. 训练时借用全局状态信息来提高算法效果。是后文提到的VDN方法的改进。 6. 接上一条,QMIX设计一个神经网络来

丨汀、的博客 5472

前端之异步JS

前端之异步JS预备知识异步概述什么是同步什么是异步线程JS是单线程的异步简介异步的两种使用方式callbacks (老派异步)callbacks 异步情况callbacks 同步情况promise (新派异步)Promises 对比 callbacks介绍异步JSJS异步执行的函数setTimeout()setInterval() 预备知识 异步的本质 **事件队列: ** 像promise这样的异步操作被放入事件队列中,事件队列在主线程完成处理后运行,这样它们就不会阻止后续JavaScript代码的运行。

weixin_46372074的博客 1317

23、资产分散化与有效前沿:投资组合优化的核心策略

本文深入探讨了现代投资组合理论的核心概念,包括分散投资的重要性、均值-方差优化框架以及有效前沿的构建与应用。通过案例分析和数学模型,阐述了如何通过科学方法降低投资组合风险并实现最优风险收益权衡。文章还介绍了实际应用中的求解方法与决策流程,为投资者提供系统的投资组合优化指导。

cc789的博客 114

大话前端:深入探索JavaScript异步机制

在JavaScript的并发模型中,理解宏任务和微任务如何被事件循环处理是至关重要的。通过这个餐厅的比喻,我们可以直观地理解,虽然JavaScript是单线程的,但通过事件循环的宏任务和微任务,它可以高效地处理多个任务,就像一位熟练的服务员一样,能够在众多任务中游刃有余。

weixin_43903608的博客 1517

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

深入理解Javascript-JS异步和事件循环

深入理解Javascript-JS异步和事件循环 前言 想想接触js已经很久了,也没有写过一篇关于js异步的文章。于是今天准备写一写js的异步,希望对想了解的同行们有所帮助 首先需要说明的是这里讨论的是浏览器里的js,而不是服务端上的js,比如node。 node和浏览器中的js的异步还是多少有些不同的,如果想了解node中的异步或者事件循环,可以参考我的另一篇文章Node 事件循...

小辣抓 1946

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

前端JavaScript面试技巧-笔记

基础知识:  原型 原型链  作用域 闭包  异步 单线程 JS-Web-API:  DOM操作  Ajax  事件绑定 开发环境:  版本管理  模块化  打包工具 运行环境:  页面渲染  性能优化 几道面试题 JS中使用typeof能得到哪些类型?(考点:JS变量类型) 何时使用(3等号)何时使用==?(考点:强制类型转换) window.onload和DOMCont...

wuzhaoqing325的博客 429

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

一探前端开发中的JS调试技巧

js调试技巧

叶叶茵的博客 4145

前端面试:js同步与异步问题

前言 我本来是打算写一篇co源码精读(为啥读co,因为它短),然鹅发现自己存在一系列基础问题没有搞透彻,打算写一个js基础系列文章,总结自己的理解(copy),希望与你在学习路上一同进步。首先问问自己当面试官问到js中的同步和异步,这个问题该怎么回答?理解一个问题无非是what-why-how js同步和异步问题是什么-->为什么会产生异步问题-->如何解决。 一、JavaScrip...

weixin_34121282的博客 1595

JavaScript异步函数的优雅封装与实战指南

在现代前端开发中,异步操作几乎无处不在。从网络请求到文件读写,从定时器到事件处理,JavaScript的执行环境充满了异步场景。在ES6之前,我们主要依靠回调函数来处理异步操作,但这常常导致"回调地狱"的问题,代码变得难以维护和理解。

wenyang12的博客 1168

JavaScript常用前端框架和库浅谈_前端框架设计-js

技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。较、计算等。* 注意Moment.js的日期格式,使用合适的格式字符串进行日期的格式化和解析。技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。

m0_60388292的博客 1945

前端 js 异步流程

js 是单线程的,也就代表 js 只能一件事情一件事情执行,那如果一件事情执行时间太久,后面要执行的就需要等待,需要等前面的事情执行完成,后面的才会执行。所以为了解决这个问题,js 委托宿主环境(浏览器)帮忙执行耗时的任务,执行完成后,在通知 js 去执行回调函数,而宿主环境帮我们执行的这些耗时任务也就是异步任务js 本身是无法发起异步的,但是 es5 之后提出了 Promise 可以进行异步操作。

一个前端开发者 331

前端人必藏!10个JavaScript实战技巧,让你从菜鸟变大神

嘿,前端打工人!写JavaScript代码时,是不是经常被各种小问题搞得头秃?想不想偷偷掌握一些“开挂”技巧,让代码跑得又快又稳,还能在同事面前露一手?今天就掏心窝子分享10个超实用的JavaScript实战技巧,涵盖ES6+新特性、React/Vue开发高频操作、性能优化等热门方向,每句代码都配详细注释,保证一看就会!话不多说,赶紧搬好小板凳!

前端大白话 992

保证前端数据实时性 --- js异步轮询

不管在何种模式的开发中,经常会遇到“前端数据实时性”的问题。本文将讨论一种“保持前端数据实时性的一种办法”。js异步轮询。 1:首先分析一下这个问题: 数据实时性,你也许会说,如果用户能够每一秒都刷新一下页面,不就实时了?对的。只要每隔多长时间请求一下服务器,就能保证前端数据的实时性。 那为什么“服务器总是这么被动的等着被访问呢”? 这个问题是关键:因为http协议是请求-响应式的

字符集-utf8 1万+

JS前端面试-异步和单线程

JS前端面试-异步和单线程一、单线程和异步二、应用场景三、callbeck hell(回调地狱)和promise四、问题解答1.同步和异步的区别是什么?2.手写promise加载一张图片3.前端使用异步的场景4.场景题setTimeout五、小结 题目 1.同步和异步的区别是什么 2.手写promise加载一张图片 3.前端使用异步的场景 4.场景题setTimeout 知识点 1.单线程和异步...

m0_46269977的博客 768

Jackson 序列化 / 反序列化注解 完整版笔记

Jackson 序列化 / 反序列化注解 完整版笔记

handsome_sai的博客 301
上一篇: 前端技巧第六期JavaScript对象
下一篇: 前端技巧第八期JavaScript中断网络请求
everyStudy
博客等级 码龄4年 292粉丝 65原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值