Harmony鸿蒙编写0基础入门到精通Day11--TypeScript篇

news/2025/12/5 22:23:15/文章来源:https://www.cnblogs.com/yangykaifa/p/19313770

JavaScript到这里,我们的JS部分就已经结束了,接下来将会学习我们的新语言TypeScript。

TypeScript

TypeScript(简称 TS)是微软开发的一门开源编程语言,它是 JavaScript 的超集(Superset)—— 这意味着所有合法的 JavaScript 代码都是合法的 TypeScript 代码,同时 TypeScript 在 JavaScript 基础上增加了静态类型系统,并扩展了更多特性。

因为浏览器只支持js语言,所以我们需要一些组件,将编写的TS代码转化为JS在浏览器上运行。

前后端交互使用xhr,后期采取node

回调地狱

“回调地狱”(Callback Hell)是 JavaScript 异步编程中因多层嵌套的回调函数导致的代码可读性差、维护困难的现象。它的核心问题是:当多个异步操作存在依赖关系(后一个操作需要前一个的结果)时,回调函数会层层嵌套,形成 “金字塔” 式的代码结构,最终变得难以理解和修改。

为什么会出现回调地狱?

JavaScript 是单线程语言,处理异步操作(如网络请求、文件读写、定时器)时,必须通过回调函数指定操作完成后的逻辑。如果异步操作存在依赖(比如 “先获取用户信息→再用用户 ID 获取订单→再用订单 ID 获取商品”),后一个操作的回调必须嵌套在前一个操作的回调中。随着依赖步骤增加,嵌套层级会越来越深,形成 “地狱”。

典型示例:回调地狱长什么样?

假设我们需要模拟三个依赖的异步操作,用嵌套回调实现会是这样:

// 模拟异步操作:获取用户
function getUser(userId, callback) {setTimeout(() => {console.log("1. 获取用户信息成功");callback({ id: userId, name: "小明" }); // 回调传递用户数据}, 1000);
}
// 模拟异步操作:用用户ID获取订单
function getOrder(userId, callback) {setTimeout(() => {console.log("2. 根据用户ID获取订单成功");callback({ orderId: "order_001", userId }); // 回调传递订单数据}, 1000);
}
// 模拟异步操作:用订单ID获取商品
function getProduct(orderId, callback) {setTimeout(() => {console.log("3. 根据订单ID获取商品成功");callback({ productId: "prod_123", orderId }); // 回调传递商品数据}, 1000);
}
// 多层嵌套的回调(回调地狱)
getUser(101, (user) => {getOrder(user.id, (order) => {getProduct(order.orderId, (product) => {console.log("最终结果:", product);// 如果还有更多步骤,这里会继续嵌套...});});
});

这段代码的问题:

  • 层级过深(像 “金字塔” 一样向右延伸),阅读时需要逐层查找逻辑。
  • 维护困难:修改某一步逻辑时,需要在多层嵌套中定位。
  • 错误处理繁琐:每个回调都要单独处理错误,容易遗漏。

如何解决回调地狱?

核心思路是避免嵌套,让代码 “纵向扁平”,用 Promise 链式调用替代嵌套。

Promise

Promise 代表一个尚未完成但最终会有结果的异步操作(如网络请求、文件读写、定时器等)。它有且仅有三种状态,且状态一旦改变就不可逆

  • pending(等待中):初始状态,异步操作尚未完成。
  • fulfilled(已成功):异步操作完成,结果可用(由 resolve 触发)。
  • rejected(已失败):异步操作出错,原因可用(由 reject 触发)。

基本用法:创建与使用 Promise

通过 new Promise(executor) 创建实例,executor 是一个立即执行的函数,接收两个参数:

  • resolve(value):异步成功时调用,将状态转为 fulfilled,并传递结果 value
  • reject(error):异步失败时调用,将状态转为 rejected,并传递错误 error(通常是 Error 对象)。
// 模拟“读取文件”的异步操作(1秒后随机成功/失败)
const readFilePromise = new Promise((resolve, reject) => {setTimeout(() => {const success = Math.random() > 0.3; // 70% 概率成功if (success) {resolve("文件内容:Hello World"); // 成功时传递结果} else {reject(new Error("文件不存在")); // 失败时传递错误}}, 1000);
});

处理异步结果

Promise 实例通过以下方法定义状态改变后的逻辑,且这些方法返回新的 Promise,因此支持链式调用

1. then(onFulfilled?, onRejected?)
  • 作用:处理 fulfilled 或 rejected 状态的结果。
  • 参数:
    • onFulfilled:状态为 fulfilled 时执行,接收 resolve 传递的 value
    • onRejected:状态为 rejected 时执行,接收 reject 传递的 error(可选,通常用 catch 替代)。
  • 返回值:新的 Promise,其状态由回调函数的返回值决定(若返回 Promise,则跟随其状态;否则直接 fulfilled)。
2. catch(onRejected)
  • 作用:专门处理 rejected 状态,等价于 then(null, onRejected)
  • 优势:更清晰地集中捕获错误(包括 then 回调中抛出的错误)。
3. finally(onFinally)
  • 作用:无论状态是 fulfilled 还是 rejected,都会执行(如关闭加载动画、清理资源)。
  • 特点:不接收参数(无法获取成功 / 失败的结果),返回新的 Promise(状态与原 Promise 一致)。
readFilePromise.then((content) => {console.log("读取成功:", content);return content.toUpperCase(); // 返回处理后的值,传给下一个then}).then((upperContent) => {console.log("转换为大写:", upperContent); // 输出:读取成功的内容的大写形式}).catch((error) => {console.log("出错了:", error.message); // 捕获所有上游错误(如“文件不存在”)}).finally(() => {console.log("操作结束(无论成败)"); // 必然执行});

async/await

async/await 是 ES2017(ES8)引入的语法糖,基于 Promise 实现,用于简化异步代码的编写。它让异步逻辑的写法更接近同步代码,解决了 Promise 链式调用可能带来的代码冗余问题,进一步提升了可读性和可维护性。

核心作用

  • async:修饰函数,表明该函数内部有异步操作,函数的返回值会自动包装为一个 Promise(无论是否显式返回 Promise)。
  • await:只能在 async 函数内部使用,用于 “等待” 一个 Promise 完成,暂停当前函数执行,直到 Promise 状态变为 fulfilled(成功)或 rejected(失败),再继续执行后续代码。

基本用法

1. async 函数的定义

在函数声明、函数表达式、箭头函数前添加 async 关键字,即可定义一个 async 函数:

// 函数声明
async function fn1() {}
// 函数表达式
const fn2 = async function () {};
// 箭头函数
const fn3 = async () => {};

async 函数的返回值规则

  • 若返回非 Promise 值(如 123{a:1}),则自动包装为 Promise.resolve(返回值)
  • 若返回 Promise,则直接返回该 Promise(状态由其自身决定)。
  • 若抛出错误(throw new Error(...)),则自动包装为 Promise.reject(错误)

示例:

async function test() {return 100; // 等价于 return Promise.resolve(100)
}
test().then(res => console.log(res)); // 输出:100
async function test2() {throw new Error("出错了"); // 等价于 return Promise.reject(new Error("出错了"))
}
test2().catch(err => console.log(err.message)); // 输出:出错了
2. await 的使用

await 后必须跟一个 Promise 对象(若不是,会自动用 Promise.resolve() 包装),作用是 “等待” 该 Promise 完成:

  • 若 Promise 成功(fulfilled),await 会返回 Promise 的结果(resolve 的值)。
  • 若 Promise 失败(rejected),await 会抛出错误(需用 try/catch 捕获)。

示例:用 async/await 处理异步操作

// 模拟一个异步请求(返回Promise)
function fetchData() {return new Promise((resolve) => {setTimeout(() => {resolve({ name: "张三", age: 20 });}, 1000);});
}
// 用async/await调用异步函数
async function getUser() {// 等待fetchData的结果(1秒后返回)const user = await fetchData();console.log(user); // 输出:{ name: "张三", age: 20 }(1秒后执行)return user;
}
getUser();

错误处理

await 等待的 Promise 若失败(rejected),会抛出错误,需用 try/catch 捕获(替代 Promise 的 catch 方法):

示例:处理异步错误

function riskyTask() {return new Promise((resolve, reject) => {setTimeout(() => {reject(new Error("操作失败!")); // 模拟失败}, 1000);});
}
async function handleTask() {try {// 等待可能失败的Promiseconst result = await riskyTask();console.log("成功:", result); // 若成功则执行(此处不会执行)} catch (error) {// 捕获失败的错误console.log("失败:", error.message); // 输出:失败:操作失败!}
}
handleTask();

与 Promise 链式调用的对比

async/await 本质是 Promise 的语法糖,但比链式调用更直观。

Promise 链式调用

javascript

运行

fetchUser().then(user => fetchOrder(user.id)).then(order => fetchProduct(order.id)).then(product => console.log(product)).catch(err => console.log(err));
  • async/await 写法

    javascript

    运行

    async function getResult() {try {const user = await fetchUser();const order = await fetchOrder(user.id);const product = await fetchProduct(order.id);console.log(product);} catch (err) {console.log(err);}
    }
    getResult();

显然,async/await 的代码更接近同步逻辑,层级扁平,可读性更高。

node.js的安装

https://nodejs.org/zh-cn/download/

进入网址后,按照步骤一步步安装即可,不要下载最新版就行。

数据请求

在编程中,“数据请求” 通常指通过网络(如 HTTP/HTTPS)从服务器获取或提交数据(如 API 接口调用)。不同环境(浏览器 / Node.js)有不同的实现方式。

数据请求的核心目的

前端发起数据请求,本质是通过 HTTP/HTTPS 协议与后端接口通信,获取后端存储的数据(如你的商品列表、用户信息),或提交前端数据(如表单、订单),最终服务于业务逻辑(如渲染商品、展示用户信息)。

核心特点:异步性(请求需要时间,不会阻塞前端代码执行,必须通过特定方式处理结果)。

我们使用一个京东案例,采用原生Ajax实现异步。

Document
  • 中国大陆-北京
    中国大陆版
    中國港澳版
    中國台灣版
    京东全球版
  • 你好,先登录免费注册
  • 切换企业版
  • 购物车
  • 我的订单
  • 我的京东
  • 企业采购
  • 商家服务
  • 网页导航
  • 手机京东
  • 网站无障碍
<script>//let xhr = new XMLHttpRequest()xhr.open('get', "http://localhost:8889/data", true)xhr.send()xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {// console.log(xhr.responseText);let jds = JSON.parse(xhr.responseText)// console.log(jds);jds.myData.jds.forEach(element => {document.querySelector('.app').innerHTML += `
${element.content}
${element.title}
¥${element.price}
${element.store}
`});}} </script>

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

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

相关文章

2025年下半年上海ISO三体系认证机构全方位评测与选择指南

摘要 随着2025年企业国际化进程加速,ISO三体系认证(ISO9001、ISO14001、ISO45001)成为上海地区企业提升管理水平和市场竞争力的关键。行业数据显示,2024年上海ISO认证市场规模同比增长15%,预计2025年下半年需求将…

鲜花

习惯了 空欢喜 学会了 不哭泣 每颗珍珠都曾是痛过的沙粒 我在等你 找到你 一直到太阳升起 多少次坠下谷底也能抱住自己 山上的风 地心的力 生命向上长成了自己 那时你会看到春野漫地 从失眠 到失意 从失落 到失去 多少…

常用adb+hdc指令

adb指令 查看连接设备adb devices 导出logcat日志adb logcat > 本地路径/logcat.txt 开启/关闭wifi(需要root)adb shell svc wifi disable/enable 打开应用adb shell am start 包名/Activity 关闭应用adb shell am …

黑马C++ 通讯录管理系统

点击查看代码 #include <iostream> #include <string> using namespace std;#define MAX 1000 // 最大人数 // 联系人结构体 struct Person {string m_Name; // 姓名int m_Sex; // 性别:1男 2女int m_A…

高级语言程序设计课程第八次个人作业

这个作业属于哪个课程:https://edu.cnblogs.com/campus/fzu/gjyycx 这个作业要求在哪里:https://edu.cnblogs.com/campus/fzu/gjyycx/homework/15590 学号:<102500401> 姓名:<林含悦> 11.13 1.2.3.6.7…

01背包

01背包模板

题解:P11811 [PA 2015] 人赢 / Mistrzostwa

废话 蒟蒻的第一篇题解! 正文 (内含一组 hack,如果你只 WA 第 18 个点)。 楼上的各位大佬,讲题思路已经很详细了。 因此这篇题解主要的目的是讲几个易错点。 那就看看我的“死亡回放”吧。 错误一 30pts。 死亡原…

详细介绍:GraphQL:让前端自己决定要什么数据

详细介绍:GraphQL:让前端自己决定要什么数据pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

2025.12.5

没课早起但是躺一天,洗澡,录入团课记录

实用指南:Configuration of TCP/IP with SSL and TLS for Database Connections

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20232420 2025-2026-1 《网络与系统攻防技术》实验八实验报告

1.实验内容 1)编写一个含有表单的HTML 2)编写JavaScript并尝试注入攻击 3)正常安装、启动MySQL,建库、创建用户、修改密码、建表 4)编写PHP网页,连接数据库,进行用户认证 5)最简单的SQL注入,XSS攻击测试 6)安装DVW…

BZOJ1278 向量 vector

给定 \(n\) 个向量 \((x_i,y_i)\)。选出若干个向量,最大化向量和的模长,输出其平方。 \(1 \leq n \leq 10^5\)。考虑弱化条件。我们不妨找到一条直线 \(l\),最大化向量和在 \(l\) 上投影的长度。容易证明,一定能找…

14.jdbc第三步PreparedStatement防sql注入

1.首先要明白什么是sql注入、怎么做①sql注入理解: 通过将不可信输入伪装成 SQL 语法片段,篡改原始 SQL 的语法结构,迫使数据库执行非预期的非法操作。② 怎样做通过 URL 参数传参或者其他传参方式将含有sql语法的参…

详细介绍:【STL源码剖析】从源码看 heap:元素的 “下沉” 与 “上浮”

详细介绍:【STL源码剖析】从源码看 heap:元素的 “下沉” 与 “上浮”2025-12-05 21:34 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: au…

大信息环境搭建从零开始(十四)CentOS 7 系统更新源更换详解:阿里云镜像源配置完整指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年度安全狗狗驱虫药品牌排行榜:专业评测助力科学养宠

摘要: 春冬季是宠物寄生虫高发期,选择安全有效的驱虫药成为养宠家庭首要关切。本文基于产品成分、临床数据、用户反馈及第三方权威检测,梳理出十大安全可靠的狗狗驱虫品牌,重点解析其核心优势与使用规范,为宠物主…

实用指南:Vue编程式路由导航

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Ubuntu 22.04 与 24.04 常用操作命令

Ubuntu 22.04 与 24.04 常用操作命令 适用场景:系统管理员、开发人员针对 Ubuntu 22.04 LTS(Jammy Jellyfish)与 24.04 LTS(Noble Numbat)的日常运维 特别说明:Ubuntu 无 24.02 版本,推测为笔误,以下基于官方 …

【Java】String

目录前言内容概览更新记录String的创建1.直接创建2.String方法String常用API注意点String本身的特点1.String的对象是不可变字符串对象2.双引号创建的字符串对象存储在常量池中,且内容相同只能存储一份3.new String创…

拒绝智商税!2025最新学习机榜单发布,十大热门机型横向对比,一看就懂

随着教育智能硬件迈入“深水区”,2025年末的学习机市场已从单纯的硬件参数竞赛,转向教育资源厚度与AI技术有效性的综合较量。面对品牌宣传中各类“顶级”标签,消费者更需要一份基于真实产品力、剥离营销话术的理性参…