JavaScript(六)---【回调、异步、promise、Async】

news2024/11/20 18:32:35

零.前言

JavaScript(一)---【js的两种导入方式、全局作用域、函数作用域、块作用域】-CSDN博客

JavaScript(二)---【js数组、js对象、this指针】-CSDN博客

JavaScript(三)---【this指针,函数定义、Call、Apply、函数绑定、闭包】-CSDN博客

JavaScript(四)---【执行上下文、hoisting(提升)、严格模式、事件】-CSDN博客

JavaScript(五)---【DOM】-CSDN博客

一.回调

1.1简介

回调”是作为参数传递给另一个函数的函数

这种技术允许函数调用另一个函数回调函数可以在另一个函数完成后运行

1.2什么时候使用回调函数

现在假设有一个业务需求:”先计算两个数的和,再将和输出,并且我们可以随时终止输出和

或许有的读者会很轻松的写出如下代码:

    <script>
        function printData(result){
            console.log(result);
        }
        function calculator(x,y){
            let sum = x + y;
            return sum;
        }
        let result = calculator(5,5);
        printData(result);
    </script>

我们将计算和输出分别用两个函数来完成,但是这样会有一个问题,那就是每次我们都需要使用两个函数,比较麻烦

此时,可能有读者又会写出另一种风格的代码:

    <script>
        function printData(result){
            console.log(result);
        }
        function calculator(x,y){
            let sum = x + y;
            printData(sum);
        }
        calculator(5,5);
    </script>

在“calculator函数中调用printData函数”,这样每次只需要调用一次“calculator”函数就可以了,但是这样仍然有一个问题,那就是:“无法随时禁止打印的过程

那么此时就用到我们的回调函数了,将printData函数作为参数传给calculator函数即可。

但在使用前,我们还是有必要先说明一下怎么使用回调函数。

1.3回调函数的使用

回调函数的使用非常简单,将需要在A函数调用的B函数作为参数传递给A函数即可。

此时B函数就成为A函数的一个形参,而在A函数中就可以利用形参来代指B函数

例如:

    <script>
        function B(){
            console.log("我是B函数");
        }

        function A(myB){
            console.log("我是A函数");
            myB();
        }
        A(B);
    </script>

效果:

注意

在将B函数作为参数传递给A函数时,实参不能带有括号,只需要写“函数名”即可

而在A函数中使用形参myB”代指B函数时,则需要加上“括号

1.4问题的解决

那么搞明白回调函数的使用之后,我们来是用回调函数解决这个问题。

业务需求:“先计算两数之和,再输出两数之和,并且可以随时终止输出的过程

解决思路:“我们将printData函数作为参数传递给calculator函数,在calculator函数中调用printData函数用来完成计算并输出的功能,此时如果需要终止输出的过程那么可以给calculator形参传递一个空值,用来表示此时不需要输出

    <script>
        function printData(result){
            console.log(result);
        }
        function calculator(x,y,myData){
            let sum = x + y;
            if (myData)
                myData(sum);
        }
        calculator(5,5,printData);  //此时需要输出
        calculator(10,10,undefined)    //此时不需要输出
    </script>

效果:

二.异步

2.1简介

如果大家接触过“多线程”的概念,那么“异步”应该是非常好理解的。

一个相对好理解的说法就是:“异步就是在同一时间运行多个代码段(函数、代码块等)

而官方的说法:“与其它函数并行运行的函数称为异步

给大家举一个例子:“在某一时刻,我们需要同时获得a+ba*b的值该怎么办?如果顺序执行a+b和a*b终究会有时间差,并不是同时获得。那么此时就用到了异步了,将a+b和a*b两个运算过程,同时进行

2.2常见的异步函数

js中内置了多个异步函数,便于我们调用,如果需要使用更多的异步函数,需要用到js库等

下面作者将论述几个常见的异步函数

2.3等待超时函数

等待超时函数:“setTimeout()可以指定超过指定时间后,自动执行某个函数

使用方法:

setTimeout(执行函数名,超时时间(ms))

ps:使用setTimeout会返回一个超时函数变量(该变量存储了超时函数id)

结束方法:

使用:“clearTimeout(超时函数变量)”来强制结束

注意:强制结束应该在超时函数执行前使用,否则无效

例如:

    <script>
        function myFunction(){
            console.log("我被调用了");
        }
        setTimeout(myFunction,3000)
    </script>

以上这个函数将会在:“3秒后自动被调用

可以发现setTimeout参数是一个函数,也就是说setTimeout是一个“回调函数

2.4等待间隔函数

等待间隔函数:“setInterval()可以指定每隔指定时间,执行一次函数,直到程序被关闭或者人为结束

(ps:该函数用的特别多)

使用方法:

setInterval(函数名,指定时间(ms))

ps:使用setInterval函数会返回一个异步函数变量(这个变量存储该异步函数的id)

人为结束setInterval”函数的方法:“使用clearIntervar(异步函数变量)”来强制结束setInterval

    <script>
        function interVal(){
            console.log("我是等待间隔函数,我被调用了.");
        }
        function stopInterVal(){
            clearInterval(time);
        }
        var time = setInterval(interVal,1000);
    </script>

以上是一个简单的开启关闭示例

三.promise

3.1简介

promise是一个js对象,它链接“生成代码”和“消费代码

  • “生成代码”(Producing code):指需要一些时间的代码
  • “消费代码”(Consuming code):指必须等待结果的代码

3.2使用方式

let myPromise = new Promise(function(myResolve, myReject) {
// "Producing Code"(可能需要一些时间)

  myResolve(); // 成功时
  myReject();  // 出错时
});

// "Consuming Code" (必须等待一个兑现的承诺)
myPromise.then(
  function(value) { /* 成功时的代码 */ },
  function(error) { /* 出错时的代码 */ }
);

 注意:

当“执行代码”也就是“消费代码”获得结果时,它必须调用两个回调函数之一:“myResolve、myReject

而在“消费代码”中,“function(value)代表myResolvefunction(error)代表myReject

例如:

function myDisplayer(some) {
  document.getElementById("demo").innerHTML = some;
}

let myPromise = new Promise(function(myResolve, myReject) {
  let x = 0;

// 生成代码(这可能需要一些时间)

  if (x == 0) {
    myResolve("OK");
  } else {
    myReject("Error");
  }
});

myPromise.then(
  function(value) {myDisplayer(value);},
  function(error) {myDisplayer(error);}
);

四.Async和Await

4.1简介

使用async关键字,可以使我们更方便的使用promise函数,而不是创建一个promise对象

通过在函数前面加入关键字“async”可以使函数返回“promise

使用“await”关键字,可以使函数等待“promise

4.2使用方法

例如:

async function myFunction() {
  return "Hello";
}
//等同于
async function myFunction() {
  return Promise.resolve("Hello");
}

而使用“async”和“await”可以使我们更方便的完成promise的操作,而promise操作的实质就是更安全的进行“异步操作”,因为promise可以进行失败逻辑判断处理

再例如:

<!DOCTYPE html>
<html>
<body>

<h1>JavaScript async / await</h1>

<p>请等待 3 秒(3000 毫秒)让此页面发生变化。</p>

<h1 id="demo"></h1>

<script>
async function myDisplay() {
  let myPromise = new Promise(function(myResolve, myReject) {
    setTimeout(function() { myResolve("I love You !!"); }, 3000);
  });
  document.getElementById("demo").innerHTML = await myPromise;
}

myDisplay();
</script>

</body>
</html>

上面这个代码就是更安全的“异步操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1566732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32的I2C补充说明

1.前言 前面不是开发了F407的i2c嘛&#xff0c;最近做项目有三四个i2c器件&#xff0c;项目要求用f103&#xff0c;于是看了一下f103&#xff0c;发现并没有多大区别&#xff0c;下面我会说一下异同。还有关于接收的过程也有要补充的。 2.F103 VS F407 两者之间几乎没有区别&a…

Maven 项目之快速选择环境配置文件

Maven项目中&#xff0c;多环境之间如何进行配置文件的切换。在我们开发的过程中&#xff0c;经常会出现开发环境、测试环境、生产环境等之间的切换&#xff0c;如果我们每次都去替换配置文件&#xff0c;就会跟繁琐&#xff0c;这个时候就可以创建多个环境&#xff0c;同时在对…

下载页面上的视频

引言&#xff1a;有些页面上的视频可以直接右键另存为或者F12检索元素找到视频地址打开后保存&#xff0c;但有些视频页面是转码后的视频&#xff0c;不能直接另存为视频格式&#xff0c;可以参考下本方法 以该页面视频为例&#xff1a;加载中...点击查看详情https://wx.vzan.c…

zookeeper监听集群节点的实现zkclient组件实现方案(Java版)

ZooKeeper Watcher 机制 client 向zookeeper 注册监听client注册的同时会存储一个WatchManager对象向zookeeper发生改变则notification client 并发送一个WatchManager对象,然后client再更新该对象 package com.jacky.zk.demo;import org.I0Itec.zkclient.IZkChildListener;…

LeetCode575——分糖果

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 这道题比较简单&#xff0c;但我还是花费了将近四个小时的时间去解答&#xff0c;AC的那一刻&#xff0c;终于全身舒畅&#xff0c;这道题的思路就是先求出糖果的种数&#xff0c;然后我们从题中可以得出&#x…

如何配置vite的proxy

1.前言 vite项目&#xff0c;本地开发环境可以通过配置proxy代理实现跨域请求。但是生产环境&#xff0c;该配置不生效&#xff0c;一般使用 nginx 转发&#xff0c;或者后端配置cors 2.解释 server: {port: 9000,proxy: { // 本地开发环境通过代理实现跨域&#xff0c;生产…

如何处理Flutter应用在iOS平台上的兼容性问题

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天我想和大家聊聊一个常见但令人头疼的问题——Flutter应用在iOS平台上的兼容性问题。在开发跨平台应用时&#xff0c;尤其是在Android和iOS两大平台上&#xff0c;兼容性问题总是难以避免。而Flutter&#xff0c;作为一个旨在解决…

使用OMP复原一维信号(MATLAB)

参考文献 https://github.com/aresmiki/CS-Recovery-Algorithms/tree/master MATLAB代码 %% 含有噪声 % minimize ||x||_1 % subject to: (||Ax-y||_2)^2<eps; % minimize : (||Ax-y||_2)^2lambda*||x||_1 % y传输中可能含噪 yyw % %% clc;clearvars; close all; %% 1.构…

IE浏览器兼容性问题——el-button点击失效

el-table 中经常有这种场景&#xff1a;最后一列是操作&#xff0c;只有一个图标 之前的实现是直接讲点击事件绑定到了 icon 图标上&#xff0c;这样在谷歌、edge、火狐等是没问题的&#xff0c;但是在ie浏览器下&#xff0c;就会出现点击事件无效的情况&#xff0c;点击后不会…

使用minikube安装使用单机版K8S(docker)

前置&#xff1a;作为一个开发&#xff0c;工作之余想玩一下k8s&#xff0c;但是搭建成本太高&#xff0c;所以就找到了minikube这个工具&#xff0c;快速搭建单机版k8s&#xff0c;下面是个人搭建流程&#xff0c;基于centos7&#xff0c;仅供参考。 1.下载kubectl&#xff0…

Idea2023创建Servlet项目

① Java EE 只是一个抽象的规范&#xff0c;具体实现称为应用服务器。 ② Java EE 只需要两个包 jsp-api.jar 和 servlet-api.jar&#xff0c;而这两个包是没有官方版本的。也就是说&#xff0c;Java 没有提供这两个包&#xff0c;只提供了一个规范。那么这两个包是谁提供的…

【Linux多线程】信号量以及线程池

【Linux多线程】信号量以及线程池 目录 【Linux多线程】信号量以及线程池POSIX信号量基于环形队列的生产者消费者模型 线程池 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2024.4.2 前言&#xff1a;本篇博客将会介绍Linux线程中的信号量以及线程池&#xff0c;完善生产者…

elementui 实现一个固定位置的Pagination(分页)组件

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、 elementui 实现一个固定位置的Pagination&#xff08;分页&#xff09;组件 文章目录 系列文章目录…

Python基于深度学习的人脸识别项目源码+演示视频,利用OpenCV进行人脸检测与识别 preview

​ 一、原理介绍 该人脸识别实例是一个基于深度学习和计算机视觉技术的应用&#xff0c;主要利用OpenCV和Python作为开发工具。系统采用了一系列算法和技术&#xff0c;其中包括以下几个关键步骤&#xff1a; 图像预处理&#xff1a;首先&#xff0c;对输入图像进行预处理&am…

深入剖析主机安全中的零信任机制及其实施原理

引言 在数字化转型加速与云端服务普及的大背景下&#xff0c;传统依赖边界的网络安全模式逐渐显露出其局限性。面对愈发复杂多变的威胁环境&#xff0c;零信任安全架构作为新一代的安全范式应运而生&#xff0c;尤其是在主机层面的安全实践中&#xff0c;零信任机制正扮演着至…

RabbitMQ3.x之七_RabbitMQ消息队列模型

RabbitMQ3.x之七_RabbitMQ消息队列模型 文章目录 RabbitMQ3.x之七_RabbitMQ消息队列模型1. RabbitMQ消息队列模型1. 简单队列2. Work Queues(工作队列)3. Publish/Subscribe(发布/订阅)4. Routing(路由)5. Topics(主题)6. RPC(远程过程调用)7. Publisher Confirms(发布者确认) …

防止推特Twitter账号被冻结,应该选什么代理类型IP?

在处理多个 Twitter 帐号时&#xff0c;选择合适的代理IP对于避免大规模帐户暂停至关重要。现在&#xff0c;问题出现了&#xff1a;哪种类型的代理是满足您需求的最佳选择&#xff1f;下面文章将为你具体讲解推特账号冻结原因以及重点介绍如何选择代理IP。 一、推特账号被冻结…

C# WPF编程-命令

C# WPF编程-命令 概述WPF命令模型ICommand接口RoutedCommand类RoutedUICommand类命令库 概述 使用路由事件可以响应广泛的鼠标和键盘事件&#xff0c;这些事件是低级的元素。在实际应用程序中&#xff0c;功能被划分成一些高级的任务。这些任务可通过各种不同的动作和用户界面…

如何借助API实现自动化商品采集商品,自营商城选品上货搜索无货源模式

借助API实现自动化商品采集、自营商城选品上货以及搜索无货源模式&#xff0c;通常需要以下步骤&#xff1a; 请求示例&#xff0c;API接口接入Anzexi58 确定数据源&#xff1a; 首先&#xff0c;你需要确定你的商品数据来源。这可能是其他电商平台、供应商网站、数据提供商等…

Spark 的结构化 APIs——RDD,DataFrame, Dataset, SparkSQL 使用和原理总结

文章目录 前言RDD的底层是什么?结构化 Spark主要优点和好处 DataFrame APISpark的基本数据类型Spark的结构化和复杂数据类型Schemas 和创建 DataFramesColumns 和 ExpressionsRows通用的 DataFrame 算子 The Dataset API有类型 Objects、无类型 Objects 和通用 Rows创建 Datas…