async和await简化回调函数嵌套

WPS专业版自带字体 WPS专业版其中一个好处就是自带了部分有版权的字体,就算你安装了没买授权,他也会给你在系统里面安装上这些字体,至于没授权继续用合不合规我不知道。但是带来的实实在在的好处就是有些子他支持的全啊。 /usr/share/fonts/wps-office/FZWBK.TTF: 方正魏碑_GBK,FZWeiBei\-S03:style=Regular /usr/share/fonts/wps-office/FZFSK.TTF: 方正仿宋_GBK,FZFangSong\-Z02:style=Regular /us 阅读详情

不使用回调函数的ajax请求实现(async和await简化回调函数嵌套)

在常规的服务器端程序设计中, 比如说爬虫程序, 发送http请求的过程会使整个执行过程阻塞,直到http请求响应完成代码才会继续执行, 以php为例子

$url = "http://www.google.com.hk";
$result = file_get_contents($url);
echo $result;

当代码执行到第二行时,程序便陷入了等待,直到请求完成,程序才会继续往下跑将抓取到的html输出。这种做法的好处是代码简洁明了,运行流程清晰, 容易维护。 缺点就是程序的运行速度依赖于http请求的响应时间,影响程序的运行效率。 然而, 因为web程序本身特质的原因,这种问题是避无可避的,程序依赖于http响应的结果和保证自身的迅速响应两者之间是存在矛盾的, 肯定无法兼顾。

但是在客户端程序或者非http应用的场景下是不存在类似的冲突的, 在Java或C#客户端编程中,碰到这种问题一般都是开启两个线程各干各的。而在JavaScript中,因为语言本身不支持多线程, 所以此类问题是使用回调函数来解决。

以最简单的前端ajax请求为例

 $.get("data.json", function ( response ) {
        console.log("2");
 });
 console.log("1")

代码先输出1,再输出2,整个程序执行流程并未因http请求而被阻塞,回调函数方案完美的把问题解决。 然而,这只是最简单回调函数示例,假如回调函数嵌套了许多层呢?

 

 

复制代码
$.get("data1.json", function (response) {
    $.get(response.url, function (response) {
        $.get(response.url, function (response) {
            console.log(response);
        });
    });
});
复制代码

回调嵌套的越深,代码运行逻辑就越难理清楚, 如果在上面代码的基础上再混入一些复杂的业务逻辑,那代码将会极难维护, 到时候遇到问题了剪不断理还乱的感觉肯定会让人红着眼睛骂娘。 虽然这种回调嵌套的场景在web前端开发中比较罕见, 但在nodejs服务器端开发领域还是常见的。 那如何克服这个问题?假如用php来写, 那便是一件很轻松的事了。

$response = file_get_contents("data1.json");
$response1 =   file_get_contents($response["url"]);
$response2 =   file_get_contents($response1["url"]);
echo $response;

以php发送http请求的方案来实现, 代码逻辑就清晰了许多。 在古时候 ,JavaScript想以这种方式实现ajax那就是痴人说梦,但是当JavaScript升级至es6版本后,通过特定的途径也可实现这种写法。 在网上这种写法被称之为“以同步的方式编写异步代码”,但是我觉得这种说法容易把人给搞迷糊,可以直接把这种写法称之为:“同步写法”, 因为里面的异步执行已经被隐藏了起来。 要实现这种写法必须使用async和await这两个关键字。在两个关键字是es7的范畴, es6还不支持,但是可以通过特定的工具将使用这两个关键字的代码转为es6的代码去执行, 比如说TypeScript和babel, 在此文中使用的代码示例都是由TypeScript实现。对于async和await的底层机制这里就不详述了, 以免将文章的篇幅拖的很长,这里就讲解一下这两个关键字能实现的效果。 先把上面用JavaScript实现的多层嵌套回调用同步的方式来改写, 代码如下

复制代码
async function ajax(url) {
    return new Promise(function (resolve, reject) {
        let ajaxSetting = {
            url: url,
            success: function (response) {
                resolve(response);
            },
            error: function () {
                reject("请求失败");
            }
        }
        $.ajax(ajaxSetting);
 
    });
}
 
async function run() {
    let response1 = await ajax("data1.json");
    let response2 = await ajax(response1["url"]);
    let response3 = await ajax(response2["url"]);
    console.log(response3);
}
 
//不阻塞
run();
复制代码

代码由ajax和run这两个函数组成, ajax是对jquery ajax的封装,使之能不使用回调函数就能获得ajax的响应结果。 当函数被声明为async类型时,如果这个函数要有返回值 ,并且返回值要在某个回调函数中获得,那么这个函数的返回结果就只能是一个 Promise对象,就像示例的ajax函数一样,返回值如果是其它类型那就达不到期望的效果。 Promise构造函数的参数是一个函数,resolve和reject分别是这个函数的两个参数,同时这两个参数自身也是函数类型,这两个参数有着重要的意义,在这里它们的作用就是将ajax的响应内容给返回出去,resolve表示返回正常状况下的值, reject表示返回异常状态下的值。按照传统的编码方式, 可以将reject看作是抛出了一个异常,像throw "请求失败", 这样,在函数调用的外部可以用try catch进行捕获。将值传出去为什么要通过这两个参数呢?因为没辙啊, 试想一下,ajax的回调函数中使用return语句, 意义何在?因此也只能变向的通过Promise将返回值扔给外部的调用者。 所以,使用async和await的第一个要点就是

当函数要获得异步结果时,可以函数声明为async类型, 函数的返回值设为Promise类型对象,而Promise中的resolve和reject是用来向async函数返回结果的, 功效如同普通函数的return语句。

async类型函数要怎么使用呢?有两种方法,一种是直接调用, 直接调用的话函数前面async关键字就被忽略了, 调用函数返回的结果就是一个Promise对象, Promise对像如何使用在这里不进行深究,大致就是像下面这样的写法

ajax("data1.json").then(function( response ){
……
});

还是以回调函数的形式出现,改进代码所带来的意义并没有体现。

另一种方法是在调用函数时加上await关键字,await的意义就在于接收async函数中的Promise对象中resolve和reject传递的值 ,而且除非resolve和reject这两个函数在回调函数中被调用到了, 否则代码就一直被阻塞在那里?换句话说, resolve和reject的调用是用来通知await等待结束,代码可以继续执行了。 这种写法不就是之前想方设法想实现的同步写法么?跟php的写法区别在于多了 await、async、Promise这三个概念, 但是在不考虑其中的内部运行原理的话, 代码的执行流程上已经和同步的写法没一丝区别了。有一点需要注意, 假如需要在函数中使用await调用,那么这个函数也必须被声明为async类型, 否则编译出错, 程序无法正常运行。 所以, 第二个要点就是

await就是用来等待Promise对象中resolve和reject这两个函数的执行的,并且将这两个函数传递的参数当作返回结果赋给变量,如同run函数中的代码示例那样。 别外, await必须被夹在两个async中间, 一个是await调用的函数,一个是await所在的函数。

至于Promise中的reject,就是用来抛异常的, 在外await调用之外可使用try catch捕获,代码如下

复制代码
async function run() {
    try {
        let response1 = await ajax("data1.json");
        let response2 = await ajax(response1["url"]);
        let response3 = await ajax(response2["url"]);
        console.log(response3);
    } catch (ex) {
        console.log(ex);
    }
}
复制代码
ThingsBoard集群部署之k8s 今天终于有时间去搞这个啦,拖了很久了,一直没时间,因为我本地没有那么多机器资源,开虚拟机不够,如果租用阿里云服务器,需要有充值的时间,因为这个费用是按小时付费,需要有连贯的时间来搞才行,今天恰好有时间,就开始搞了,弄成功搞出来了,特地写博客记录下来。 阅读详情

相关推荐

GD32F303实战:用定时器4触发ADC2+DMA,实现10ms精准采样1024点的完整流程

本文详细介绍了在GD32F303微控制器上使用Timer4触发ADC2配合DMA传输,实现10ms精准采样1024点的完整方案。从硬件架构设计、时钟树配置到定时器参数计算,提供了完整的工程实现流程和常见问题排查方法,适用于工业传感器监测等高实时性场景。

weixin_29194693的博客 433

不使用回调函数的ajax请求实现(async和await简化回调函数嵌套)

在常规的服务器端程序设计中, 比如说爬虫程序, 发送http请求的过程会使整个执行过程阻塞,直到http请求响应完成代码才会继续执行, 以php为例子 $url = "http://www.google.com.hk"; $result = file_get_contents($url); echo $result; 当代码执行到第二行时,程序便陷入了等待,直到请求完成,...

diebianyi1454的博客 532

智能车轮腿组‘定点排雷’科目全解析:从雷区识别到姿态控制

本文深入解析了智能车竞赛轮腿穿越组‘定点排雷’科目的核心技术。从构建鲁棒的视觉识别系统,到融合编码器与IMU进行厘米级定位,再到实现框内高精度旋转的姿态控制,提供了一套完整的从感知到执行的闭环技术方案,助力参赛队伍攻克这一高难度科目。

weixin_29161719的博客 640

深入浅出JS—21 异步代码处理方案之async-await

在开发中,我们通常会遇到需要多个串联异步请求的方案,即要依靠第一个异步请求结果来发起下个异步请求,这时如果采用Promise会形成回调地狱,不利于代码的管理,所以采用async和await关键字来解决 异步代码处理方案 一个异步请求:Promise 多个串联异步请求:Promise(可能会用到Promise.all/race等进行结果处理) 多个串联异步请求:async-await(本质上是Promise+生成器的语法糖) async和await是包装好的语法糖、但我们不至于用,还是要一步一步进行推.

分享前端知识,记录前端进阶 1183

SolidWorks 2022 学习(一)软件安装

接下来是安装SolidWorks,右键SolidWorks.2022.SP0.Premium.DVD.iso,选择装载。然后以管理员身份运行SolidWorks_Flexnet_Server目录下的server_install.bat。更改需要安装的产品,以及安装路径,并勾选接受条款,点击现在安装,会弹出如下窗口。然后以管理员身份运行setup.exe,开始安装solidworks。下载链接会在文章末尾给出,下载完成的文件如下图所示。双击注册表文件,然后点击确定。保持不动,点击确定,开始安装。

qq_38383364的博客 3130

小秋SLAM入门实战ubuntu所有文章汇总

ubuntu 终端如何停止快速打印的输出以及恢复命令 ubuntu 终端如何快速打开当前路径下的图形化窗口界面? killall -9用途用法 ps -xu | grep这个命令的用途 linux 下 top命令显示的是内存是堆内存吗? zip分割和合并 关闭除当前 GNOME 终端窗口以外的所有其他 GNOME 终端窗口 如何在安装系统后设置短密码 【如何使用getrusage获取消耗的CPU时间和进程使用的最大物理内存】 【webots安装使用教程】 Linux系统下查看当前运行的进程和线程的几种方法

小秋 AI SLAM 入门实战教程 1405

async 与await 解决请求回调地狱(多层请求嵌套)

async 与await 解决请求回调地狱(多层请求嵌套) 1.async(异步) 与 await(同步) 方法 解决请求回调地狱 是通过promise来实现的,所以使用这两个方法进行测试也是要模拟返回一个promise对象===手动返回。 *没有返回promise对象将无法实现异步同步 (错误写法) function test1(){ setTimeout(()=>{ return ...

qq_41709082的博客 8903

两组相机(或三维点)对齐方法介绍及实现代码(求解相似变换,包含旋转R、平移t、尺度s)

  这个变换用于将生成的稀疏重建场景对齐到真值上。由于SfM(Structure from Motion,运动恢复结构)求解的结果是尺度未定的,所以重建场景与真值之间不仅会相差一个旋转与平移,还会存在尺度缩放。待求解的问题可以描述为:已知一组相机(个数为m)的位姿真值Rgt、tgt和预测位姿Rpred、tpred,现要将预测值对齐到真值上。它们之间会相差一个相似变换Msimilarity,包括尺度s、旋转量R、平移量t,可以根据如下步骤进行求解:    1 求解旋转R   首先计算所有m个相机的位姿差异总和

zeeq的博客 3926

async 和 await 理解笔记

一.为什么要使用async 和 await 作用:用于解决回调函数嵌套问题,使代码可读性更高,解决回调地狱问题。(嵌套的例子就不举了,一抓一堆) 二.async 和 await 使用说明? async用于修饰一个函数, 表示一个函数是异步的 await必须写在 async函数中, 一般后面跟的 promise对象, 会等待 promise成功的结果 作用:await会阻塞 async函数的执行, 让代码可读性更高 await只会等待成功的结果, 失败了会报错, 报错需要通过 .catch() 方法处理

摸鱼小队 1209

计算电磁学(三)有限差分方法

有限差分方法(FDM)是一种数值处理方法,通过将偏微分方程变换为一组代数方程,通过求解代数方程组来得到原边值问题的近似值。由于有限差分法非常简单,所以也特别的稳定高效。其中时域有限差分方法(FDTD)是电磁分析中的常用方法。在计算电磁学中,常用有限差分方法(finite difference equations)来替代微分方程。一个有限差分法通常包括三个步骤将求解域划分网格用有限差分方程逼近给定的微分方程求解在给定边界条件和初始状态下的方程常用的网格模型方阵斜方阵三角阵圆形阵。

CCC_B的博客 1640

elevation mapping算法3之使用D435i相机离线或在线订阅点云和tf关系生成高程图

本文主要学习使用D435i相机发出的点云作为高程图的点云输入,如何离线输入点云生成高程图,进一步学习如何在线订阅点云生成高程图。

重点记录机器人和自动驾驶相关领域的技术,尤其是计算机视觉,视觉SLAM等,不仅有前言文献或必备算法的学习,也会有实际应用的点滴经验 3489

异步编程工具Promise与Async/Await:解决前端开发中的嵌套回调地狱

如果数组中的所有Promise对象都变为fulfilled(已成功)状态,那么Promise.all返回的Promise对象也会变为fulfilled状态,其结果是一个数组,包含了数组中的所有Promise对象的结果。Promise.all是一个静态方法,它可以接收一个Promise对象的数组作为参数,返回一个新的Promise对象,该对象的状态和结果取决于数组中的所有Promise对象的状态和结果。使用Promise进行异步编程时,可以将多个Promise对象链接在一起,形成一个Promise链。

Apple_Boy的博客 787

Unity内存优化:从崩溃到流畅的终极指南

Emscripten 为 WebAssembly 设定的内存布局(Static、Stack 和 Heap)为开发者提供了一个清晰的内存管理框架。理解这些内存区域的特性和用途,有助于开发者在 WebGL 项目中更有效地管理内存,优化性能,减少内存使用峰值。在 Unity WebGL 中,Dynamic Memory 是 UnityHeap 的主要组成部分,负责存储游戏运行时所需的各种数据。Dynamic Memory 主要分为两类:Managed Memory 和 Native Memory。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 358

javascript-不使用回调函数的ajax请求实现(async和await简化回调函数嵌套)

不使用回调函数的ajax请求实现(async和await简化回调函数嵌套) 在常规的服务器端程序设计中, 比如说爬虫程序, 发送http请求的过程会使整个执行过程阻塞,直到http请求响应完成代码才会继续执行, 以php为例子 $url = "http://www.google.com.hk"; $result = file_get_contents($url); echo $result;...

cxu123321的博客 1078

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

NTscan扫描工具

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

Promise解决回调嵌套问题及终极解决方案async 和 await

一、promise 1.异步函数 与 回调函数的说明 回调函数: 把一个函数当成参数传递, 将来特定的时机调用, 这个函数就叫回调函数 什么时候会用到回调函数, 异步的时候 延时器 setTimeout ajax (传入函数, 作为回调, 将来在特定时机调用) console.log(1) setTimeout(function() { console.log(2) ...

拆解SEO逻辑,深挖技术架构与流量获取路径。 2168

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【今日前端】callback、promise和async await 区别

callback、promise和async await 区别callback👇callback到回调地狱promise链式编程💡👇Generator👇async await 👈了解再多一点借鉴😇 callback👇 callback 顾名思义 回调,不禁让人想起回调地狱。 什么是回调🦑 function say(value){ console.log(calue) } function execute(func, val){ func(val) } execute(say, 'hello worl

weixin_43841308的博客 2396

node.js异步控制流程 回调,事件,promise和async/await

首先nodejs的事件循环: 最开始的main函数就是一个事件,事件处理完了之后,返回到事件循环,如果上个事件处理过程有异步IO的,那么在本次的事件循环中就会判断该异步IO是否符合,符合的话就去执行这个事件,如果什么事件都没有了的话,那么整体推出   写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观。 首先上结论:推荐使用async/await或者co/y...

Allen_Walker_QAQ的博客 396

api es7 删除所有数据_es7在vs code中怎么去掉async await的报错波浪线

匿名用户1级2016-03-08 回答JavaScript 中最蛋疼的事情莫过于回调函数嵌套问题。以往在浏览器中,因为与服务器通讯是一种比较昂贵的操作,因此比较复杂的业务逻辑往往都放在服务器端,前端 JavaScript 只需要少数几次 AJAX 请求就可拿到全部数据。但是到了 webapp 风行的时代,前端业务逻辑越来越复杂,往往几个 AJAX 请求之间互有依赖,有些请求依赖前面请求的数据,有些...

weixin_39966602的博客 222

ES7 中使用 async/await 解决回调函数嵌套问题

JavaScript 中最蛋疼的事情莫过于回调函数嵌套问题。以往在浏览器中,因为与服务器通讯是一种比较昂贵的操作,因此比较复杂的业务逻辑往往都放在服务器端,前端 JavaScript 只需要少数几次 AJAX 请求就可拿到全部数据。但是到了 webapp 风行的时代,前端业务逻辑越来越复杂,往往几个 AJAX 请求之间互有依赖,有些请求依赖前面请求的数据,有些请求需要并行进行。还有在类似 node.

babybk的博客 9655

Async和Await

1.async: 可以作用在任何方法前, 返回的是一个Promise对象 函数内部return的返回值, 会成为then回调函数的参数 async作用的方法,如果内部出现报错,可以被promise的catch方法捕获 常规使用,一般都会通过try catch进行有可能报错的代码处理 2.await: await只能作用在async修饰的方法中,不能单独使用,如果使用报错 await是会阻塞代码执行 正常情况 await后面跟着一个Promise对象; 返回的是Promise对象的成功后结果; 如果是一个普

weixin_53718041的博客 133

promise与async和await的区别

什么是Async/Await?   async/await是写异步代码的新方式,以前的方法有回调函数和Promise。   async/await是基于Promise实现的,它不能用于普通的回调函数。   async/await与Promise一样,是非阻塞的。   async/await使得异步代码看起来像同步代码,这正是它的魔力所在。 Async/Await语法  假设函数getJSON返回值是 Promise,并且 Promise resolves 有一些JSON 对象。我们只想调用它并且记录.

潘晓宇(panxiaoyu)的专栏 335

promise与async和await的使用

基础回顾 阻塞代码实例 首先,我们新建一个 test.txt 文件,内容如下: 111 然后,我们来编写一个 main.js 文件,代码如下: var fs = require('fs') var str = fs.readFileSync('./test.txt') console.log(str.toString()) console.log("程序结束了") 运行结果如下: 可以看到,程序是按顺序执行的。也就是说阻塞是按顺序执行的 按顺序执行程序 逻辑控制起来的确是好,但是..

我想月薪过万的博客 523

Nodejs进阶系列- 08 使用 Promise/await/async解决 callback hell

由于nodejs的异步特性,我们经常使用callback函数,但是如果在callback里面又要callback的话,会发现多层嵌套结构非常糟糕,所以被称为callback Hell(“回调地狱“),采用Promise来解决这个问题。 const fs = require("fs"); const path = require("path"); const util = require("ut...

沙漠之鹰的博客 552

Vue第5天知识点:promise:异步函数与回调函数的说明嵌套、promise基本语法、解决回调函数问题以及优化、封装axios的发送、面试题循环队列以及宏任务与微任务、async和await

promise 异步函数 与 回调函数的说明 异步函数: 定时器setTimeout, ajax (异步函数的执行, 不会阻塞主线程代码的执行) 回调函数: 把一个函数当成参数传递, 将来特定的时机调用, 这个函数就叫回调函数 什么时候会用到回调函数, 异步的时候 ajax success error console.log(1) setTimeout(function() { console.log(2) setTimeout(function() {

m0_46597922的博客 995

async 与 awite

当我们使用 await 等待一个 Promise 对象时,JavaScript 引擎会暂停当前函数的执行,直到 Promise 对象执行完毕并返回结果才会继续执行下面的代码。async 函数是一个返回 Promise 对象的函数,它在函数体内部使用 await 来等待 Promise 对象执行结果。这个函数使用 async 关键字声明,返回一个 Promise 对象,在函数体内部使用 await 等待异步操作完成,然后将得到的数据返回。

Mxy18851251178的博客 327

vue+百度地图——promise、async和await的简单使用

searchAddress是一个搜索地址的函数,为了在实现路径规划和路书的功能时方便使用,这里将它通过 promise 封装起来 searchAddress(val) { return new Promise((resolve) => { // promise封装异异步函数传递的消息 var address = new BMap.L...

景严-的博客 557
上一篇: Angularjs中的$Http与$resource
下一篇: Js类和继承的实现
SunsCheung
博客等级 码龄11年 30粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值