鸿蒙开发学习|Promise的介绍与在鸿蒙中的使用

Promise的介绍与在鸿蒙中的使用

异步编程

学习Promise的开始,我们要先了解异步编程
一般代码的执行是单线程的机制,就是按次序执行,执行完一个任务后,再执行下一个,如果我们在页面加载的同时时候执行一个请求,拿到数据后映射到界面上,这时我们就需要异步操作来执行这个请求

异步就相当于从主线程发射一个子线程来完成任务,每一个任务有一个或者多个回调函数,前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务不用等前一个任务结束就会执行

所以程序执行顺序与任务的排列顺序是不一致的,异步的
在这里插入图片描述

回调函数

刚刚我们提到了回调函数
回调函数的定义非常简单:一个函数被当做一个实参传入到另一个函数(外部函数),并且这个函数在外部函数内被调用,用来完成某些任务的函数。就称为回调函数
回调函数的两种写法(实现效果相同):

  1. 将回调函数写在外边
    const text = () => {console.log('执行代码');}setTimeout(text, 1000)
  1. 直接将回调函数写成参数
    setTimeout(()=>{console.log('执行代码');}, 1000)

这段代码中的 setTimeout 就是一个消耗时间较长的过程,它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 1 秒,然后执行回调函数 “text”,在文本中输出执行代码
setTimeout会在子线程中等待1秒,但是主线程的运行不会受到影响!例如以下代码

    setTimeout(()=>{console.log('执行代码');}, 1000)console.log('123456');

在这里会先打印出来123456(主线程),然后一秒后在文本中输出执行代码(子线程)

回调地狱

在学习Promise之前我们需要先了解什么是回调地狱以及产生回调地狱的原因

概念,当一个回调函数嵌套一个回调函数的时候就会出现一个嵌套结构,当嵌套的数量足够多的时候就会出现回调地狱的情况.

举个例子

比如我们需要发送三个ajax请求

  1. 第一个正常请求
  2. 第二个需要第一个请求的返回值作为参数
  3. 第三个需要第二个请求的返回值作为参数
$.ajax({url: '我是第一个请求',type: 'get',success (res) {// 现在发送第二个请求$.ajax({url: '我是第二个请求'type:'post',data: { a: res.a, b: res.b },success (res1) {// 进行第三个请求$.ajax({url: '我是第三个请求',type:'post',data: { a: res1.a, b: res1.b },success (res2) { console.log(res2) }})}})}
})

不用解释就可以看出来当前代码的可维护性差的特点,所以这时就需要需要我们的Promise去解决回调地狱的问题.

Promise(承诺)

Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。

Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。

Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。

  1. 只有异步操作的结果可以决定是哪一种状态,其他任何操作都无法改编这个状态(承诺)
  2. Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected
  3. 只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

无论何时调用,只要执行结束就可以一直得到这个结果

最基本的用法是通过构造函数实例化一个Promise对象,同时传入一个带有两个参数的函数,通常称为executor函数。

executor函数接收两个参数:resolve和reject,分别表示异步操作成功和失败时的回调函数。

目的就是更优雅的书写复杂的异步任务

语法格式

首次创建一个Promise对象,并将其作为一个方法的返回值

// 在test方法中设定返回值为Promise对象,为其传入一个返回的类型,就比如说number
async test(): Promise<number> {return new Promise((resolve, reject) => {//业务逻辑代码,你想要执行异步任务的代码if (...){//如果进入你设计的代码逻辑,则执行resolve回调函数并将执行数字作为参数传递;resolve(0)}else{//否则执行reject回调函数并传递一个错误对象作为参数。reject(new Error('Random number is too small'))}})
}

在另外一个地方进行当前方法的调用

this.test().then((res:number)=>{console.info(`number is ${res}`);
}).catch((error:BusinessError)=>{console.error(error.message);
})

上述代码中,then方法的回调函数接收Promise对象的成功结果作为参数,并将其输出到控制台上。如果Promise对象进入rejected状态,则catch方法的回调函数接收错误对象作为参数,并将其输出到控制台上。

如果你想表达的是成功回调,你可以在内部调用函数reslove('一般情况下是后端返回的成功数据)。如果你想表达的是失败回调,你可以调用reject('一般情况下是后端返回的失败信息').

Promise链式调用

then方法返回的是一个新的Promise实例(注意:不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法

  1. 实际案例:
    我想要实现在一个数组中查看一个帖子,但是我最终的目的是得到这个帖子下面的所有评论,这该怎么实现呢?
  2. 实现思路:
    先从一个接口中获取这个帖子的信息,然后通过该帖子的帖子id从而获取到该帖子下的所有评论
pajax({url:"http://localhost:3000/news",data : {author : "james"}
}).then(res=>{return pajax({url : "http://localhost:3000/comments",data : {newsId : res[0].id}})
}).then(res=>{console.log(res);
}).catch(err=>{console.log(err);
})

这样也就解决了上边我们所提到的回调地狱的问题,使用Promise链式调用,

Promise.all()

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例

  • 语法格式
    // Promise.all一次性处理多个异步请求返回数据Promise.all([promise1, promise2,promise3, promise4]).then(res => {this.flag1 = res[0];this.flag2 = res[1];this.flag3 = res[2];this.flag4 = res[3];})

Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会调用Promise.reslove() [该方法可自行了解]自动将参数转为 Promise 实例,再进一步处理。
说那么多白话没用,我们可以根据一个案例,就可以明白Promise.all()的用途了。

  • 实际案例

如果你想实现一个效果:在一个页面中,等到页面中所有的请求返回数据后,再渲染页面,该怎么实现呢?(在实际开发中我们会看到loading加载页面,等数据返回完后,loading加载页面会消失,整个页面就展现出来了,增强用户的体验。)

  // aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。aboutToAppear(): void {// Promise.all一次性处理多个异步请求返回数据Promise.all([promise1, promise2,promise3, promise4]).then(res => {this.flag1 = res[0];this.flag2 = res[1];this.flag3 = res[2];this.flag4 = res[3];})}build() {if (this.flag1 != -1) {//组件1}if (this.flag2 != -1) {//组件2}if (this.flag3 != -1) {//组件3}if (this.flag4 != -1) {//组件4}}

执行aboutToAppear()方法在页面执行前获取数据,获取到数据后,再通过flag控制组件的显示.

有关aboutToAppear()方法具体使用方法,请了解鸿蒙应用具体生命周期.

总结

虽然解决异步编程的终极解决方案是async和await,但是它们也是基于Promise封装而来的,不过了解Promise也是很重要的

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

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

相关文章

第二课 Model模型资源导入设置检查与优化

上期我们学习了最简单的audio音效的优化&#xff0c;接下来我们继续model模型资源的优化&#xff0c;我将汇总各路大神关于模型优化的思路和方法供你和我学习。 首先我们还是要把我们优化的目标重申一遍&#xff1a; 优化的目标 1.文件体积尽可能小 2.内存占用尽可能小 3.…

小米路由器用外网域名访问管理界面

本文在Redmi AX3000 (RA81)设置&#xff0c;其他型号路由器的管理界面端口可能各不相同。 开始之前需要保证路由器SSH功能正常&#xff0c;如果没有SSH可以参考这里。 1. 给WAN口开放80端口 可以通过下载mixbox的firewall插件或者其他防火墙插件开放端口。 2. 把域名解析到路…

一次需升级系统的wxpython安装(macOS M1)

WARNING: The scripts libdoc, rebot and robot are installed in /Users/用户名/Library/Python/3.8/bin which is not on PATH. 背景&#xff1a;想在macos安装Robot Framework &#xff0c;显示pip3不是最新&#xff0c;更新pip3后显示不在PATH上 参看博主文章末尾 MAC系统…

Leetcode 求根节点到叶节点数字之和

使用深度优先搜索 DFS 来做 我提供的代码使用的是 深度优先搜索&#xff08;DFS&#xff0c;Depth-First Search&#xff09; 算法。以下是具体的算法思想和实现步骤的解释&#xff1a; 算法思想 树的路径代表数字&#xff1a; 树中每条从根节点到叶子节点的路径可以看作一个整…

IDEA:2023版远程服务器debug

很简单&#xff0c;但是很多文档没有写清楚&#xff0c;wocao 一、首先新建一个远程jvm 二、配置 三、把上面的参数复制出来 -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 四、然后把这串代码放到服务器中&#xff08;这里的0.0.0.0意思是所有IP都能访问&a…

计算机毕业设计 | SpringBoot+vue汽车资讯网站 汽车购买咨询管理系统(附源码+论文)

1&#xff0c;绪论 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理汽车资讯网站的相关信息成为必然…

RedHat系统配置静态IP

1、执行nmtui命令进入字符配置界面如下图所示 2、选择编辑连接进入 3、选择编辑进入后&#xff0c;将IPv4设置为手动模式后&#xff0c;选择显示后进行ip地址、网关、DNS的配置&#xff0c;配置完成后选择确定退出编辑 4、进入主界面后选择启用连接进入后&#xff0c;选择启用&…

Android开发教程案例源码分享-匹配动画多个头像飘动效果

Android开发教程案例源码分享-匹配动画多个头像飘动效果 匹配往往出现多个头像飘动&#xff0c;吸引人点击&#xff0c;有时出现的位置还不固定 一、思路&#xff1a; 用MotionLayout 二、效果图&#xff1a; 看视频更直观点&#xff1a; Android开发教程案例源码分享-匹配…

设计LRU缓存

LRU缓存 LRU缓存的实现思路LRU缓存的操作C11 STL实现LRU缓存自行设计双向链表 哈希表 LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;缓存是一种常见的缓存淘汰算法&#xff0c;其基本思想是&#xff1a;当缓存空间已满时&#xff0c;移除最近最少使…

SAM-Med2D 训练完成后boxes_prompt没有生成mask的问题

之前对着这这篇文章去微调SAM_Med2D(windows环境),发现boxes_prompt空空如也。查找了好长时间问题SAM-Med2D 大模型学习笔记&#xff08;续&#xff09;&#xff1a;训练自己数据集_sam训练自己数据集-CSDN博客 今天在看label2image_test.json文件的时候发现了一些端倪: 官方…

39页PDF | 毕马威_数据资产运营白皮书(限免下载)

一、前言 《毕马威数据资产运营白皮书》探讨了数据作为新型生产要素在企业数智化转型中的重要性&#xff0c;提出了数据资产运营的“三要素”&#xff08;组织与意识、流程与规范、平台与工具&#xff09;和“四重奏”&#xff08;数据资产盘点、评估、治理、共享&#xff09;…

在 macOS 和 Linux 中,波浪号 `~`的区别

文章目录 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~ 在 macO…

【LeetCode每日一题】——485.最大连续 1 的个数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 数组 二【题目难度】 LeetCode 三【题目编号】 485.最大连续 1 的个数 四【题目描述】 给定…

windows 操作系统下载 Android源码教程

前言 开始我是装了hyber-v 虚拟机ubuntu 的&#xff0c;然而非常的卡顿且难用。因此我尝试在windows上使用repo&#xff0c;因此有了这篇文章 补充 第二天发现编译源码也需要linux命令因为源码中的很多脚本都是.sh的 因此最终通过安装WSL解决&#xff08;在window应用商店就…

单片机进阶硬件部分_day2_项目实践

设计要求 从绘制原理图到画PCB板&#xff0c;完成智能云衣柜项目 STM32 &#xff08;Modbus&#xff09;云IOT衣物云端管理 华为PCB布线规范 基于IoT的智享家主控系统 步骤分析 需求分析 器件选型绘制原理图&#xff08;器件连接&#xff09;PCB布局、布线泪滴、铺铜、添加丝印…

接口上传视频和oss直传视频到阿里云组件

接口视频上传 <template><div class"component-upload-video"><el-uploadclass"avatar-uploader":action"uploadImgUrl":on-progress"uploadVideoProcess":on-success"handleUploadSuccess":limit"lim…

Flutter:photo_view图片预览功能

导入SDK photo_view: ^0.15.0单张图片预览&#xff0c;支持放大缩小 import package:flutter/material.dart; import package:photo_view/photo_view.dart;... ...class _MyHomePageState extends State<MyHomePage>{overrideWidget build(BuildContext context) {return…

【Linux】详解僵尸进程与孤儿进程(Z僵死状态引发的内存泄漏与处理办法)

&#x1f308; 个人主页&#xff1a;谁在夜里看海. &#x1f525; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 丢掉幻想&#xff0c;准备斗争 目录 引言 一、僵尸进程 1.子进程的创建与退出 2.进程表 3.僵尸状态产生 4.直观感受一下&#xff1a; 二、…

基于微信小程序的科学健身助手的设计与实现

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

【Pytorch】torch.utils.data模块

torch.utils.data模块主要用于进行数据集处理&#xff0c;是常用的一个包。在构建数据集的过程中经常会用到。要使用data函数必须先导入&#xff1a; from torch.utils import data 下面介绍几个经常使用到的类。 torch.utils.data.DataLoader DataLoader(dataset, batch_…