当前位置: 首页 > news >正文

JavaScript--明明白白Promise (Park One)

明明白白Promise (Park One)

Promise是一种用于处理异步操作的特殊对象。它代表了一个尚未完成但最终会完成的操作,并可以在操作完成后返回结果或错误。

Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。当一个Promise被创建时,它处于pending状态。操作可以是异步的,当操作成功完成时,Promise将转为fulfilled状态,并提供相应的结果。相反,如果操作失败,则Promise将转为rejected状态,并提供错误的原因。

使用Promise,可以通过链式调用then()方法来处理异步操作的结果。then()方法接受两个回调函数作为参数:一个用于处理操作成功完成时的结果,另一个用于处理操作被拒绝时的错误。这种链式调用的方式使得代码更加清晰和易于维护。

除了then()方法,Promise还提供了其他方法,如catch()用于捕获错误,finally()用于指定无论Promise状态如何都要执行的操作。

Promise的出现使得JavaScript中的异步编程更加优雅和可读,避免了回调地狱(callback hell)的问题。它已经成为现代JavaScript中处理异步操作的一种标准方式。

Promise 在各种开源库中已经实现,现在标准化后被浏览器默认支持。

传统实现,代码会陷入回调地狱的例子:

function getUser(userId, callback) {// 异步操作获取用户数据setTimeout(() => {const user = { id: userId, name: 'John' };callback(user);}, 1000);
}function getPosts(user, callback) {// 异步操作获取用户的帖子数据setTimeout(() => {const posts = ['Post 1', 'Post 2', 'Post 3'];callback(posts);}, 1000);
}function getComments(post, callback) {// 异步操作获取帖子的评论数据setTimeout(() => {const comments = ['Comment 1', 'Comment 2', 'Comment 3'];callback(comments);}, 1000);
}getUser(1, (user) => {getPosts(user, (posts) => {getComments(posts[0], (comments) => {console.log(comments);});});
});

我们需要获取用户数据、帖子数据和评论数据。由于这些操作都是异步的,我们使用了多个嵌套的回调函数来处理它们。这样的代码结构难以阅读和维护,尤其是在处理更复杂的异步操作时。

Promise 的优点之一是可以通过链式调用来避免回调地狱问题,使代码结构更加清晰和可读。一个 promise 必须有一个 then 方法用于处理状态改变

Promise 包含pendingfulfilledrejected三种状态

  • pending 指初始等待状态,初始化 promise 时的状态
  • resolve 指已经解决,将 promise 状态设置为fulfilled
  • reject 指拒绝处理,将 promise 状态设置为rejected
  • promise 是生产者,通过 resolvereject 函数告之结果
  • promise 非常适合需要一定执行时间的异步任务

状态一旦改变将不可更改,promise 没有使用 resolvereject 更改状态时,状态为 pending

console.log(new Promise((resolve, reject) => {});
); //Promise {<pending>}

当更改状态后

console.log(new Promise((resolve, reject) => {resolve("fulfilled");})
); //Promise {<resolved>: "fulfilled"}console.log(new Promise((resolve, reject) => {reject("rejected");})
); //Promise {<rejected>: "rejected"}

promise 创建时即立即执行即同步任务,then 会放在异步微任务中执行,需要等同步任务执行后才执行。

let promise = new Promise((resolve, reject) => {resolve("fulfilled");console.log("success");
});
promise.then(msg => {console.log(msg);
});
console.log("ss-s.cc");
promise` 操作都是在其他代码后执行,下面会先输出 `ss-s.cc` 再弹出 `success

promise 的 then、catch、finally 的方法都是异步任务

程序需要将主任务执行完成才会执行异步队列任务

const promise = new Promise(resolve => resolve("success"));
promise.then(alert);
alert("ss-s.cc");
promise.then(() => {alert("success");
});

下例在三秒后将 Promise 状态设置为 fulfilled ,然后执行 then 方法

new Promise((resolve, reject) => {setTimeout(() => {resolve("fulfilled");}, 3000);
}).then(msg => {console.log(msg);},error => {console.log(error);}
);

状态被改变后就不能再修改了,下面先通过resolve 改变为成功状态,表示promise 状态已经完成,就不能使用 reject 更改状态了

new Promise((resolve, reject) => {resolve("操作成功");reject(new Error("请求失败"));
}).then(msg => {console.log(msg);},error => {console.log(error);}
);

动态改变

如果你想在没有使用 Promise 的情况下动态改变异步操作的处理方式,一个可能的方法是使用回调函数作为参数,并在需要改变处理方式时更改回调函数。

function asyncOperation(callback) {setTimeout(() => {const data = 'Async data';callback(data);}, 1000);
}// 初始情况下使用默认的回调函数处理异步操作结果
asyncOperation((result) => {console.log('默认处理方式:', result);
});// 动态改变处理方式,使用新的回调函数处理异步操作结果
const newCallback = (result) => {console.log('新的处理方式:', result.toUpperCase());
};asyncOperation(newCallback);

我们使用默认的回调函数来处理异步操作结果。然后,我们定义了一个新的回调函数 newCallback,它会将结果转换为大写形式。通过将新的回调函数传递给 asyncOperation 函数,我们可以动态地改变处理方式。

使用Promise可以更方便地实现动态改变异步操作的处理方式。

function asyncOperation() {return new Promise((resolve, reject) => {setTimeout(() => {const data = 'Async data';resolve(data);}, 1000);});
}// 初始情况下使用默认的处理方式处理异步操作结果
asyncOperation().then((result) => {console.log('默认处理方式:', result);});// 动态改变处理方式,使用新的处理方式处理异步操作结果
const newHandler = (result) => {console.log('新的处理方式:', result.toUpperCase());
};// 创建一个新的 Promise,并在其上添加新的处理方式
const newPromise = asyncOperation().then(newHandler);// 在新的 Promise 上继续添加其他处理方式
newPromise.then((result) => {console.log('额外的处理方式:', result.length);});

then的介绍及使用方法

什么是then?then() 是 Promise 对象上的方法之一,用于处理 Promise 的成功状态(fulfilled)。它接受两个参数:一个是处理成功状态的回调函数,另一个是处理失败状态(rejected)的回调函数(可选)。

语法:

promise.then(onFulfilled, onRejected)
  • onFulfilled 是一个函数,它会在 Promise 对象被成功解决时调用,并接收解决(fulfilled)状态的值作为参数。这个函数可以处理异步操作的结果,执行其他操作,或者返回一个新的值或 Promise 对象。
  • onRejected 是一个可选的函数,它会在 Promise 对象被拒绝(rejected)时调用,并接收拒绝状态的原因作为参数。这个函数可以处理错误,进行错误处理或返回一个新的错误。

.then() 方法返回一个新的 Promise 对象,可以通过链式调用多个 .then() 方法来串联处理多个异步操作的结果。

const promise = new Promise((resolve, reject) => {setTimeout(() => {const randomNum = Math.random();if (randomNum < 0.5) {resolve(randomNum); // 操作成功完成,返回结果} else {reject(new Error('操作失败')); // 操作被拒绝,返回错误}}, 1000);
});promise.then((result) => {console.log('操作成功:', result);return result * 2; // 返回一个新的值},(error) => {console.log('操作失败:', error);throw new Error('新的错误'); // 抛出一个新的错误}
).then((newResult) => {console.log('新的操作成功:', newResult);},(newError) => {console.log('新的操作失败:', newError);}
);

then的链式调用:

可以在一个 Promise 对象上多次调用 .then() 方法,以便依次处理异步操作的结果。每个 .then() 方法都返回一个新的 Promise 对象,使得你可以在后续的 .then() 方法中继续处理结果,形成一个链式的处理流程。

function asyncOperation() {return new Promise((resolve, reject) => {setTimeout(() => {const data = 'Async data';resolve(data);}, 1000);});
}asyncOperation().then((result) => {console.log('第一个处理步骤:', result);return result.toUpperCase();}).then((result) => {console.log('第二个处理步骤:', result);return result.split(' ');}).then((result) => {console.log('第三个处理步骤:', result);return result.reverse();}).then((result) => {console.log('最终结果:', result);}).catch((error) => {console.log('发生错误:', error);});

注意点:

  1. 返回值传递:.then() 方法可以返回一个值或一个新的 Promise 对象。如果回调函数返回一个值,该值将被包装在一个已解决(fulfilled)状态的 Promise 对象中,并作为下一个 .then() 方法的输入。如果回调函数返回一个 Promise 对象,下一个 .then() 方法将等待该 Promise 对象解决,并将其解决值作为输入。

  2. 异步操作的顺序:.then() 方法是异步的,它们会在 Promise 的解决(fulfilled)状态时被调用,而不会阻塞后续代码的执行。因此,在链式调用中的每个 .then() 方法中的代码可能会在其他 .then() 方法之前或之后执行。确保你理解和处理好异步操作的顺序和依赖关系。

  3. 错误处理:.then() 方法链中的任何一个步骤发生错误时,错误会被传递到后续的 .catch() 方法或链中的下一个 .then() 方法的错误处理回调函数中。使用 .catch() 方法来捕获和处理链式调用中的错误,确保错误被适当地处理和传递。

  4. 异常处理:如果在 .then() 方法中的回调函数中抛出异常(使用 throw 语句),异常会被自动捕获并传递给后续的 .catch() 方法或链中的下一个 .then() 方法的错误处理回调函数中。

  5. 链式调用的返回值:.then() 方法返回一个新的 Promise 对象,它代表了当前 .then() 方法的处理结果。这使得你可以通过链式调用多个 .then() 方法来形成一个处理流程。同时,返回的 Promise 对象可以用于后续的 .then() 方法的调用或错误处理。

  6. 注意 Promise 链的结束:在 .then() 方法链中,确保在链的最后使用 .catch() 方法或 .finally() 方法来处理最终的成功或失败状态,以避免未处理的 Promise 拒绝(rejected)状态导致的未捕获错误。

catch
Promise 对象的 .catch() 方法用于捕获和处理 Promise 链中发生的错误。当 Promise 链中的任何一个 Promise 被拒绝(rejected)时,错误会被传递到 .catch() 方法中进行处理。
.catch() 方法接受一个回调函数作为参数,该回调函数会在 Promise 被拒绝时被调用。回调函数可以接收一个参数,即拒绝的原因(通常是一个 Error 对象),并在该函数中执行错误处理逻辑。

fetch('https://api.example.com/data').then(response => {// 处理响应return response.json();}).then(data => {// 处理数据console.log(data);}).catch(error => {// 处理错误console.error('发生错误:', error);});

如果 fetch() 请求失败或者 .then() 中的任何一个操作抛出异常,错误将被传递到 .catch() 中进行处理。您可以在 .catch() 回调函数中执行适当的错误处理,例如打印错误消息或执行备选操作。

使用 .catch() 方法可以有效地捕获和处理 Promise 链中的错误,确保代码在出现异常情况时具有适当的容错和错误处理机制。

catch 用于失败状态的处理函数,等同于 then(null,reject){}

建议使用 catch 处理错误将 catch 放在最后面用于统一处理前面发生的错误

const promise = new Promise((resolve, reject) => {reject(new Error("Notice: Promise Exception"));
}).catch(msg => {console.error(msg);
});

catch 可以捕获之前所有 promise 的错误,所以建议将 catch 放在最后。下例中 catch 也可以捕获到了第一个 then 返回 的 promise 的错误。

new Promise((resolve, reject) => {resolve();
})
.then(() => {return new Promise((resolve, reject) => {reject(".then ");});
})
.then(() => {})
.catch(msg => {console.log(msg);
});

错误是冒泡的操作的,下面没有任何一个then 定义第二个函数,将一直冒泡到 catch 处理错误

new Promise((resolve, reject) => {reject(new Error("请求失败"));
})
.then(msg => {})
.then(msg => {})
.catch(error => {console.log(error);
});
catch 也可以捕获对 then 抛出的错误处理new Promise((resolve, reject) => {resolve();
})
.then(msg => {throw new Error("这是then 抛出的错误");
})
.catch(() => {console.log("33");
});

也可以捕获其他错误,下面在 then 中使用了未定义的变量,将会把错误抛出到 catch

new Promise((resolve, reject) => {resolve("success");
})
.then(msg => {console.log(a);
})
.catch(reason => {console.log(reason);
});

使用建议
建议将错误要交给catch处理而不是在then中完成,不建议使用下面的方式管理错误

new Promise((resolve, reject) => {reject(new Error("请求失败"));
}).then(msg => {console.log(msg);},error => {console.log(error);}
);

处理机制,在 promise 中抛出的错误也会被catch 捕获

const promise = new Promise((resolve, reject) => {throw new Error("fail");
}).catch(msg => {console.log(msg.toString());
});

注意:可以将上面的理解为如下代码,可以理解为内部自动执行 try…catch

const promise = new Promise((resolve, reject) => {try {throw new Error("fail");} catch (error) {reject(error);}
}).catch(msg => {console.log(msg.toString());
});

但像下面的在异步中 throw 将不会触发 catch,而使用系统错误处理

const promise = new Promise((resolve, reject) => {setTimeout(() => {throw new Error("fail");}, 2000);
}).catch(msg => {console.log(msg);
});

下面在then 方法中使用了没有定义的hd函数,也会抛除到 catch 执行,可以理解为内部自动执行 try…catch

const promise = new Promise((resolve, reject) => {resolve();
})
.then(() => {hd();
})
.catch(msg => {console.log(msg.toString());
});
在 catch 中发生的错误也会抛给最近的错误处理const promise = new Promise((resolve, reject) => {reject();
})
.catch(msg => {hd();
})
.then(null, error => {console.log(error);
});

fanlly的介绍与用法

Promise 对象的 .finally() 方法用于指定不论 Promise 是否成功完成或被拒绝,都要执行的逻辑。无论 Promise 的状态如何,.finally() 方法都会在 Promise 链中的最后执行。

.finally() 方法接受一个回调函数作为参数,该回调函数在 Promise 完成或被拒绝时被调用。它不接收任何参数,因此无法获取 Promise 的结果或拒绝原因,仅用于执行一些清理操作或在 Promise 完成后执行一些必要的逻辑。

fetch('https://api.example.com/data').then(response => {// 处理响应return response.json();}).then(data => {// 处理数据console.log(data);}).catch(error => {// 处理错误console.error('发生错误:', error);}).finally(() => {// 执行清理操作或其他逻辑console.log('完成处理');});

注意:无论状态是resolve 或 reject 都会执行此动作,finally 与状态无关。

图片加载的综合例子:


function loadImage(url) {return new Promise((resolve, reject) => {const img = new Image();img.onload = function() {resolve(img);};img.onerror = function() {reject(new Error('图片加载失败'));};img.src = url;});
}function displayImage(image) {const container = document.getElementById('image-container');container.appendChild(image);
}function handleImageLoad(url) {loadImage(url).then(image => {displayImage(image);}).catch(error => {console.error('加载图片出错:', error);}).finally(() => {console.log('清理工作完成');});
}// 调用示例
const imageUrl = 'https://example.com/image.jpg';
handleImageLoad(imageUrl);

首先定义了 loadImage() 函数,它接受一个图片的URL作为参数,并返回一个 Promise 对象。在 Promise 的构造函数中,我们创建一个新的 Image 对象,并设置其 onload 和 onerror 事件处理程序。当图片加载成功时,我们调用 resolve() 方法,将加载的图片对象传递给 .then() 方法。当图片加载失败时,我们调用 reject() 方法,将一个错误对象传递给 .catch() 方法。

在 handleImageLoad() 函数中,我们调用 loadImage() 函数来加载图片,并使用 .then() 方法来处理加载成功的情况。在 .then() 方法的回调函数中,我们调用 displayImage() 函数来显示加载的图片。如果加载出现错误,我们使用 .catch() 方法来处理错误情况。无论加载成功还是失败,我们都使用 .finally() 方法来进行清理工作。

欢迎点赞,关注! 谢谢!

相关文章:

JavaScript--明明白白Promise (Park One)

明明白白Promise (Park One) Promise是一种用于处理异步操作的特殊对象。它代表了一个尚未完成但最终会完成的操作&#xff0c;并可以在操作完成后返回结果或错误。 Promise有三种状态&#xff1a;pending&#xff08;进行中&#xff09;、fulfilled&#xff08;已完成&#…...

el-form与el-upload结合上传带附件的表单数据(后端篇)

1.写在之前 本文采用Spring Boot MinIO MySQLMybatis Plus技术栈&#xff0c;参考ruoyi-vue-pro项目。 前端实现请看本篇文章el-form与el-upload结合上传带附件的表单数据&#xff08;前端篇&#xff09;-CSDN博客。 2.需求描述 在OA办公系统中&#xff0c;流程表单申请人…...

postMessage——不同源的网页直接通过localStorage/sessionStorage/Cookies——技能提升

最近遇到一个问题&#xff0c;就是不同源的两个网页之间进行localstorage或者cookie的共享。 上周其实遇到过一次&#xff0c;觉得麻烦就让后端换了种方式处理了&#xff0c;昨天又遇到了同样的问题。 使用场景 比如从网页A通过iframe跳转到网页B&#xff0c;而且这两个网页…...

上市公司-绿色投资者数据集(2000-2022)

上市公司-绿色投资者数据&#xff08;2000-2022年&#xff09;是一份涵盖了过去二十多年中国上市公司绿色投资情况的详细数据集。该数据集包括了各上市公司的股票代码、年份、会计年度、股票简称&#xff0c;以及STPT&#xff08;特殊处理股票的标识&#xff09;&#xff0c;行…...

3 pandas之dataframe

定义 DataFrame是一个二维数据结构&#xff0c;即数据以行和列的方式以表格形式对齐。 DataFrame特点&#xff1a; 存在不同类型的列大小可变带有标签的轴可对列和行进行算数运算 构造函数 pandas.DataFrame( data, index, columns, dtype, copy)参数解释&#xff1a; 序号…...

vue-内网,离线使用百度地图(地图瓦片图下载静态资源展示定位)

前言 最近发现很多小伙伴都在问内网怎么使用百度地图&#xff0c;或者是断网情况下能使用百度地图吗 后面经过一番研究&#xff0c;主要难点是&#xff0c;正常情况下我们是访问公网百度图片&#xff0c;数据&#xff0c;才能使用 内网时访问不了百度地图资源时就会使用不了&…...

OpenFeign 万字教程详解

OpenFeign 万字教程详解 目录 一、概述 1.1.OpenFeign是什么&#xff1f;1.2.OpenFeign能干什么1.3.OpenFeign和Feign的区别1.4.FeignClient 二、OpenFeign使用 2.1.OpenFeign 常规远程调用2.2.OpenFeign 微服务使用步骤2.3.OpenFeign 超时控制2.4.OpenFeign 日志打印2.5.O…...

全自动双轴晶圆划片机:半导体制造的关键利器

随着科技的飞速发展&#xff0c;半导体行业正以前所未有的速度向前迈进。在这个过程中&#xff0c;全自动双轴晶圆划片机作为一种重要的设备&#xff0c;在半导体晶圆、集成电路、QFN、发光二极管、miniLED、太阳能电池、电子基片等材料的划切过程中发挥着举足轻重的作用。 全自…...

Android Studio 安装和使用

前些天&#xff0c;打开了几年前的一个Android Studio app项目&#xff0c;使用安卓虚拟机仿真app崩溃&#xff0c;怀疑是不是中间升级过Android Studio导致异常的&#xff0c;马上脑子一热卸载了&#xff0c;结果上次踩过的坑&#xff0c;一个没少又踩一次&#xff0c;谨以此文…...

【已解决】Java中,判断:集合中是否包含指定元素(模糊匹配)比如权限中的user:list或者是user:*这种判断

背景描述 在工作中&#xff0c;有时候&#xff0c;我们需要对list中是否包含了指定元素进行判断&#xff0c;但是&#xff0c;有时候又需要支持模糊匹配&#xff0c;这个时候怎么办呢&#xff1f; 比如权限&#xff0c;我们知道&#xff0c;权限不仅可以配置完整的路径&#…...

【基于激光雷达的路沿检测用于自动驾驶的真值标注】

文章目录 概要主要贡献内容概述实验小结 概要 论文地址&#xff1a;https://arxiv.org/pdf/2312.00534.pdf 路沿检测在自动驾驶中扮演着重要的角色&#xff0c;因为它能够帮助车辆感知道可行驶区域和不可行驶区域。为了开发和验证自动驾驶功能&#xff0c;标注的数据是必不可…...

【Spring实战】配置多数据源

文章目录 1. 配置数据源信息2. 创建第一个数据源3. 创建第二个数据源4. 创建启动类及查询方法5. 启动服务6. 创建表及做数据7. 查询验证8. 详细代码总结 通过上一节的介绍&#xff0c;我们已经知道了如何使用 Spring 进行数据源的配置以及应用。在一些复杂的应用中&#xff0c;…...

DevOps系列文章 : 使用dpkg命令打deb包

创建一个打包的目录&#xff0c;类似rpmbuild&#xff0c;这里创建了目录deb_build mkdir deb_build目标 我有一个hello的二进制文件hello和源码hello.c, 准备安装到/opt/helloworld目录中 步骤 在deb_build目录创建一个文件夹用于存放我的安装文件 mkdir helloworld在he…...

linux sed命令操作大全

经常使用&#xff0c;但有些总记不全&#xff0c;有时候经常查找&#xff0c;这次全部捋清楚做备忘&#xff0c;有需要的小伙伴欢迎收藏起来哦&#xff01; 查、增、改、删一应俱全&#xff0c;非常详细&#xff01; 目录 一、查看 查看第2行 查看第2行到第3行 查看第1行、…...

Vue2+Vue3组件间通信方式汇总(3)------$bus

组件间通信方式是前端必不可少的知识点&#xff0c;前端开发经常会遇到组件间通信的情况&#xff0c;而且也是前端开发面试常问的知识点之一。接下来开始组件间通信方式第三弹------$bus,并讲讲分别在Vue2、Vue3中的表现。 Vue2Vue3组件间通信方式汇总&#xff08;1&#xff09…...

前端基础location的使用

概念 获取当前页面的地址信息&#xff0c;还可以修改某些属性&#xff0c;实现页面跳转和刷新等。 样例展示 window.location 含义.originURL 基础地址&#xff0c;包括协议名、域名和端口号.protocol协议 (http: 或 https:).host域名端口号.hostname域名.port端口号.pathname路…...

Android JNI入门到基础

一、JNI项目创建 AS创建项目时选择NativeC 会创建一个基本的JNI项目 MainActivity中写java层的native方法 具体实现在cpp文件中 native-lib.cpp #include <jni.h> #include <string>extern "C" JNIEXPORT jstring JNICALL Java_com_cn_techvision_j…...

60.乐理基础-打拍子-V字打拍法

前置内容&#xff1a; 文字版 https://note.youdao.com/s/6FSSvGBf &#xff08;顺序参考&#xff1a;下方的视频版里面目录顺序&#xff09; 视频版 【四川音乐学院作曲硕士】教你零基础自学乐理保姆级教学-学习视频教程-腾讯课堂 文字版还有下图红框中三个专栏里的内容&a…...

列表对象的时间进行中文格式化处理

在黑马的项目学习中&#xff0c;如何将前端页面时间显示成2023年12月21日 06:23:23中文形式。 如果你想使用中文格式化日期&#xff0c;你可以将 en-US 更改为 zh-CN&#xff0c;以使用中文语言环境。以下是修改后的代码&#xff1a; result.data.items.forEach(item > {//…...

vi和vim的区别

目录 一、前言 二、vi/vim 的介绍 三、Vi/Vim 常见指令 四、vi和vim的区别 一、前言 写这篇文章的目的&#xff0c;是为了告诉大家我们如果要在终端下对文本进行编辑和修改可以使用vim编辑器。 Ubuntu 自带了 VI 编辑器&#xff0c;但是 VI 编辑器对于习惯了 Windows 下进…...

【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作

详情点击查看福利&#xff1a;【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作 目标&#xff1a; 1、熟练掌握ChatGPT提示词技巧及各种应用方法&#xff0c;并成为工作中的助手。 2、通过案例掌握ChatGPT撰写、修改论文及工作报告&#xff0c;提供…...

【解决Typora图片不是显示问题】PicGo+Github+Typora+ onedrive/坚果云 实现笔记同步

【解决Typora图片不是显示问题】PicGo、Github、Typora实现笔记同步 写在前面&#xff1a; typora笔记软件使用记录typora图片上传问题&#xff1a;原因分析&#xff1a;解决方案&#xff1a;PicGoGithubTypora 坚果云/onedrive 实现笔记同步第一步. 设置上传模式&#xff1a;u…...

使用Guava轻松创建和管理不可变集合

第1章&#xff1a;引言 大家好&#xff0c;我是小黑。今天&#xff0c;我们来聊聊一个在Java编程里超有用的话题&#xff1a;使用Guava创建和管理不可变集合。首先&#xff0c;咱们得明白&#xff0c;什么是不可变集合。简单来说&#xff0c;不可变集合就是一旦创建就不能被修…...

深入了解 Android 中的应用程序签名

深入了解 Android 中的应用程序签名 一、应用程序签名介绍1.1 应用程序签名1.2 应用程序签名的意义1.3 应用程序签名的流程1.4 应用程序签名的方案1.5 签名的重要性和应用场景 二、AOSP 的应用签名2.1 AOSP的应用签名文件路径2.2 应用程序指定签名文件 三、Android Studio 的应…...

说说 style gan 中的感知路径长度(Perceptual Path Length)

我在之前的博库中介绍了 style gan 的基本原理&#xff0c;原文中有提出感知路径长度&#xff08;Perceptual Path Length&#xff09;的概念。这是一种评价生成器质量的方式。 PPL基本思想&#xff1a;给出两个随机噪声 z 1 , z 2 ​ &#xff0c;为求得两点的感知路径长度PPL…...

基于JAVA的厦门旅游电子商务预订系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒店管理模块2.4 美食管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学生表3.2.3 学生表3.2.4 学生表 四、系统展示五、核心代码5.1 新增景点类型5.2 查询推荐的…...

uniapp中使用封装步骤条组件

针对步骤条封装完终于清清楚楚啦 先看效果&#xff1a; 附上代码&#xff1a;使用可直接复用&#xff1a;数据是写在了当前组件中&#xff0c;如有必须&#xff0c;可以使用其中的props传值stepInfos传递相应的数据&#xff0c;根据steps步数就可以控制走到哪一步啦 <temp…...

【MySQL】sum 函数和 count 函数的相同作用

力扣题 1、题目地址 1174. 即时食物配送 II 2、模拟表 配送表&#xff1a;Delivery Column NameTypedelivery_idintcustomer_idintorder_datedatecustomer_pref_delivery_datedate delivery_id 是该表中具有唯一值的列。该表保存着顾客的食物配送信息&#xff0c;顾客在某…...

在QT Creator下用CMake编译GEOS库

最近&#xff0c;想要在C下编一个可用GDAL模块的地图管理系统&#xff0c;找来找去&#xff0c;找到了GEOS。GEOS&#xff08;Geometry Engine-Open Source&#xff09;开源几何引擎 是一个用于计算几何的JTS库的 C/C实现&#xff0c;专注于地理信息系统 &#xff08;GIS&#…...

【Qt之Quick模块】4. QML语法格式及命名规范

概述 QML&#xff08;Qt Meta-Object Language&#xff09;是一种声明式语言&#xff0c;用于设计用户界面。它是由Qt框架提供的一种描述界面组件的语言&#xff0c;可以与C代码结合使用&#xff0c;用于创建跨平台的应用程序。 QML具有以下特点&#xff1a; 声明式&#xff…...

惠州营销网站建设/小程序开发公司排行榜

当今的互联网&#xff0c;用户为王。传统的用户单方面接收信息&#xff08;Web 1.0&#xff09;、用户创造信息&#xff08;Web 2.0&#xff09;的爆炸时代已经趋缓&#xff0c;互联网逐步向用户之间交流信息、分享信息的平台发展。如何打造一个优秀的社区&#xff0c;累积有价…...

做标识的网站 知乎/seo检测

对 Linux 新手非常有用的 20 个命令 http://www.oschina.net/translate/useful-linux-commands-for-newbies 对 Linux 中级用户非常有用的 20 个命令 http://www.oschina.net/translate/20-advanced-commands-for-linux-experts 对 Linux 专家非常有用的 20 个命令 http://www.…...

360度全景网站的公司/友情链接发布网

转自&#xff1a;https://blog.csdn.net/longfei_2010/article/details/79785320 1、编辑&#xff08;Editing&#xff09; Ctrl Space 基本的代码完成&#xff08;类、方法、属性&#xff09; Ctrl Alt Space 快速导入任意类 Ctrl Shift Enter 语句完成 Ctrl P 参数信息…...

apache wordpress rewrite/官网关键词优化价格

030-云E办_RabbitMQ_简单模式队列一、介绍简单模式队列1、RabbitMQ发送消息使用三个角色&#xff1a;1. producing 消息的生产者。2. queue队列&#xff1a;3. consuming 消费者&#xff1a;2、hello3、如何实现hello4、生产者和消费者&#xff0c;解读代码&#xff1a;1.生产者…...

wordpress h5模板/百度代做seo排名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022年安全员-C证试题是安全员-C证练习题高频考题覆盖&#xff01;2022安全员-C证考试题模拟考试题库及在线模拟考试依据安全员-C证考试教材。安全员-C证复审模拟考试通过安全生产模拟考试一点通上提前熟悉考试环境。…...

南宁美容网站建设/北京seo做排名

目录 1.Spring家族 2.IOC 2.1IOC原理 DI 依赖注入&#xff08;DI&#xff09;的方式&#xff1a; IOC的优势 IOC运行流程 SpringIOC支持的功能 2.2SpringIOC的应用 2.2.1BeanDefinitionRegistry 2.2.2BeanFactory 2.2.3ApplicationContext 2.2.4Bean是如何装载在s…...