JavaScript Promise 同步处理

JavaScript 中的 Promises 是一种异步编程的解决方案,它提供了一种简单的方法来处理异步操作的结果。在 JavaScript 中,Promise 对象有两种状态:pending 和 fulfilled。当一个异步操作开始时,Promise 的状态为 pending,如果异步操作成功,Promise 的状态就会变为 fulfilled,如果异步操作失败,Promise 的状态就会变为 rejected。

Promise 同步处理可以使用 async/await 来实现。

async function processPromise() {
  const result = await promise;
  console.log(result);
}

在上面的代码中,我们声明了一个 async 函数 processPromise,并在函数内部使用 await 来等待 promise 对象的结果。当 promise 对象的状态变为 fulfilled 时,await 表达式的值就会被赋值给 result 变量。

需要注意的是,async/await 只能在函数中使用。

 

使用 async/await 可以让你在 JavaScript 中编写同步风格的代码,而无需使用回调函数和链式调用。这使得代码变得更加简洁易读。

例如,如果你要执行三个异步操作,并且要按顺序执行,你可以使用 async/await 来编写代码:

async function processAll() {
  const result1 = await promise1;
  console.log(result1);
  const result2 = await promise2;
  console.log(result2);
  const result3 = await promise3;
  console.log(result3);
}

在上面的代码中,我们使用了三个 await 表达式来等待三个 promise 对象的结果,这样就可以保证 promise1、promise2、promise3 按顺序执行。

 

需要注意的是,如果 promise 对象的状态变为 rejected,await 表达式会抛出一个错误,这时你可以使用 try/catch 语句来捕获错误。

async function processAll() {
  try {
    const result1 = await promise1;
    console.log(result1);
    const result2 = await promise2;
    console.log(result2);
    const result3 = await promise3;
    console.log(result3);
  } catch (error) {
    console.error(error);
  }
}

还有一点需要注意的是,使用 async/await 会使得代码变得更加简洁,但也可能会使得代码变得更加复杂。如果你的代码中存在很多嵌套的异步操作,使用 async/await 可能会使得代码变得很难看。

 

另外,如果你的代码中有很多并发的异步操作,使用 async/await 可能会使得代码变得很慢。因为 async/await 是顺序执行的,如果存在多个并发的异步操作,它们会按顺序执行,这可能会导致性能问题。

为了解决这个问题,你可以使用 Promise.all 方法来并发执行多个异步操作

async function processAll() {
  const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3]);
  console.log(result1, result2, result3);
}

在使用 async/await 时需要考虑到它可能带来的复杂性和性能问题, 并在适当的地方使用相应的方法来优化代码。

 

另外, 为了解决async/await在并发处理上的问题,还有一个库叫做 async_hooks 可以用来优化代码。它提供了一种更灵活的方式来处理并发的异步操作。

例如, 你可以使用 async_hooks 库来实现一个并发限制器,它允许你限制同时运行的异步操作的数量。

const async_hooks = require('async_hooks');

class Limiter {
  constructor(concurrency) {
    this.concurrency = concurrency;
    this.active = 0;
    this.queue = [];
    this.hooks = async_hooks.createHook({
      init: (asyncId, type, triggerAsyncId, resource) => {
        if (this.active >= this.concurrency) {
          resource.emitBefore();
          this.queue.push(resource);
        } else {
          this.active++;
        }
      },
      before: (asyncId) => {
        if (this.queue.length > 0) {
          const resource = this.queue.shift();
          this.active++;
          resource.emitBefore();
        } else {
          this.active--;
        }
      },
    });
  }
  start() {
    this.hooks.enable();
  }
  stop() {
    this.hooks.disable();
  }
}

使用这个并发限制器可以限制同时运行的异步操作的数量, 这样就可以保证代码性能。

async_hooks 是一种非常强大的工具,它可以帮助你优化 JavaScript 中的异步代码,解决并发问题。但是需要注意的是它的使用需要一定的经验和技巧。

作者:yuzhihui
出处:http://www.cnblogs.com/yuzhihui/ 声明:欢迎任何形式的转载,但请务必注明出处!!!
本文转载于网络 如有侵权请联系删除

相关文章

  • Spring Boot 系列 —— Spring Webflux

    SpringWebflux文章目录SpringWebfluxJava函数式编程FunctionalInterface注解Functional接口Java响应式编程Reactor3Reactor3介绍响应式编程Reactor3的使用Flux和Mono的详述Flux和Mono的创建通用创建方式可编程式的创建Generate方法Create方法Handle方法Flux和Mono信息的消费和处理对Flux和Mono中的信息进行处理Springwebflux的使用引入POM编写配置文件编写主函数编写Controller测试效果Java函数式编程FunctionalInterface注解Java8提出了函数式接口的概念。所谓函数式接口,简单来说,就是只定义了单一抽象方法的接口。 【示例】@FunctionalInterface publicinterfaceIntHandler{ inthandler(inta); }复制注释FunctionalInterface用于表明IntHandler接口是一个函数式接口,该接口被定义为只包含一个抽象方法handle(),因此它符合函数式接口的定义。如果一个

  • 《手把手教你》系列技巧篇(十九)-java+ selenium自动化测试-元素定位大法之By css下卷(详细教程)

    1.简介按计划今天宏哥继续讲解css的定位元素的方法。但是今天最后一种宏哥介绍给大家,了解就可以了,因为实际中很少用。2.常用定位方法(8种)(1)id (2)name (3)classname (4)tagname (5)linktext (6)partiallinktext (7)xpath (8)cssselector(今天讲解)3.自动测试实战以百度首页为例,将CSS的各种定位方法一一讲解和分享一下。3.1大致步骤1.访问度娘首页。2.通过CSS定位到元素,点击一下。3.2使用索引定位元素在xpath中,我们使用过索引定位,因此在css中同样可以使用索引定位。这个有的也叫定位子元素或者是伪类定位元素。CSS的索引定位与xpath的索引定位有很大不同,我们还以百度首页为例我们要定位“百度一下”按钮,先定位到“百度一下”元素标签<input>的上级标签<span>,而<span>标签是<form>标签下所有<span>标签的第2个<span>,同时又是<form>标签下的第9个子标签在xpath定位

  • 金三银四跳槽季,自动化面试题预热一波

    VOL209232021-02今天距2022年311天这是ITester软件测试小栈第209次推文本文2877字,阅读约需7分钟Hello,大家好。春节过后,有的人盼望升职加薪,有的人立了新的Flag,有跳槽计划的该提上日程了。为解大伙的燃眉之急,今天分享自动化面试题预热一波,欢迎留言区补充评论✍️。一请描述一下自动化测试流程?自动化测试流程一般可以分为以下七步:编写自动化测试计划;设计自动化测试用例;编写自动化测试框架和脚本;调试并维护脚本;无人值守测试;后期脚本维护(添加用例、开发更新版本)。二自动化测试有误报过bug吗?产生误报怎么办?有误报过,有时候自动化测试报告中显示发现了bug,实际去通过手工测试去确认又不存在该bug。误报原因一般是:元素定位不稳定,需要尽量提高脚本的稳定性;开发更新了页面但是测试没有及时更新维护。三什么是PO模式?全称:pageobjectmodel简称:POM/PO,PO模式最核心的思想是分层,实现松耦合,实现脚本重复使用及脚本易维护性。PO模式主要分三层:1.基础层BasePage:封装一些最基础的selenium的原生的api方法,元素定位,框架跳

  • 金融科技面临价值重构,自主研发破局应用难题

    作者|洪七公来源|镭射财经就国内消费金融市场而言,今年头部消费金融公司纷纷开启金融科技转型,科技向金融服务渗透加快,科技与金融的联结正在为消费金融市场创造新的业绩拐点。不过,在金融强监管的趋势下,金融科技也在平衡创新与风险之间的关系。从金融科技本质上看,落脚点始终在于金融,科技与金融取长补短、深度融合,既打开金融服务增长空间,又提升展业过程中的质检、风险处置效率,真正实现科技赋能金融服务创新的价值落地。目前,银行、消费金融公司、互金机构等消费金融参与者,都通过设立金融科技子公司或金融科技分支部门,自主研发基于大数据、云计算、人工智能、区块链技术的金融科技解决方案。一方面,对自身业务进行数字化改造并应用于自营场景;另一方面,开展金融科技ToB业务,带动行业数字化转型。从互联网金融到金融科技,科技赋能金融业数字化转型已迈入深水区,由市场前端的线上化逐渐延展到中后台智能化。金融科技能在较短时间内穿透金融服务的营销、获客、风控、贷后管理以及平台整体运营,主要得益于行业数字化程度较高。拿人工智能来讲,人工智能的三驾核心马车为数据、算法、算力,数据是人工智能从实验室走到具体服务场景的基础,而消费金

  • 在Gaussian16中同时扫描两个反应坐标

    本公众号之前推送过在高斯中的两种常见势能面扫描:用高斯做势能面扫描(一):刚性扫描用高斯做势能面扫描(二):柔性扫描 可能大家都熟知,在柔性扫描中如果写了两个扫描坐标,如B15S70.1B16S70.1是依次扫描两个坐标,无法做到同时,因此得到的是一张二维势能面,总扫描点数是两个坐标扫描点数的乘积,计算量较大。然而有时候我们只想同时扫描两个反应坐标,即两个坐标同时改变,得到一条曲线。 例如,找[2+2]环加成反应的过渡态经常会碰到这种问题,对于复杂的分子结构,手动调整过渡态初猜很难合适,此时使用opt=ts找到过渡态的成功率自然也不高,这时候我们可能就想,取柔性扫描势能曲线(面)上的突跃点作为过渡态初猜,然而去扫两个坐标得到一张二维势能面未免过于耗时。 对于这种问题,笔者以往采用了两种做法:(1)写了一个小程序来产生调整键长后新的结构(不仅仅是拉进/远两个原子),然而产生的结构我并不满意,算法还需改进或者仍有bug。(2)若仅算一两步反应,那么就手动在GaussView里调整好两个键长,每次算完下载下来再调键长,这样扫描5个点就要下载、调整5次,甚是麻烦。 由于G16推出了广义内坐标

  • 浙大 CBIST团队发布高质量的多中心MRI公开数据集

    浙大生仪学院磁共振平台的CBIST团队近期公开了一批包含三位旅行志愿者在十家不同中心采集的磁共振扩散成像数据集。数据的具体描述和简要质量报告已经在ScientificData发表。神经影像研究的可重复性是近年来学界观注的热点。例如《Nature》杂志新近报道了一项神经影像数据可重复性的研究,表明不同研究团队在分析同一批数据并检验相同假设时,因处理步骤、参数的选择差异得到不一致的结论。事实上,影像数据的可重复性更会受到数据采集方法、磁共振设备硬件性能等的影响。CBIST近年来十分关注扩散成像数据在多个中心间测量的可重复性与一致性。以往的多中心研究多采用不同型号机器或不同的成像参数,突显了中心间的差异。本次公开的数据集严格控制了磁共振机型(西门子Prisma3T)和采集参数,并召集三位旅行志愿者在十家中心间穿梭采集。这些数据一方面为3T磁共振的结构成像提供比较对象,另一方面可作为中心间一致性研究的参考,同时也是数据分析算法的可重复性研究的有利资源。数据集涵盖了在10台同型号MRI扫描仪中采集了3名旅行者被试的脑部T1加权结构和多b值扩散加权成像(DWI)数据。在其中一台扫描仪内,对3名被试

  • 群邮件钓鱼软件的简单分析并拿到后台

    截图不知道从何时起,qq群邮件就成为了钓鱼软件传播的一个绝佳场所,什么“”萌妹变声器”,“破解UU加速器”。 我偶尔闲的无聊的时候,就会下载下来耗费几分钟逆(ti)向(chuan)一下.发现钓鱼软件总是要把自己服务器的账号密码写到软件里面。 现在我们来一起捋一捋这个事情。首先,这些钓鱼软件会通过控件覆盖的方式盗取Steam账号密码,并且为了过Steam的安全验证需要将ssfn开头的授权文件上传到病毒作者服务器。这个文件控件覆盖可以看到,这里的两个输入框和登录按钮都不是Steam自身的。并且是浮在空着的。然后通过腾讯快速的“漏洞”,即通过本地的“localhost.ptlogin2.qq.com”,拿到cookies和token相关的登录信息,借此群发邮件。这块有很多人都聊过了,也很简单。网上资料也很多,我就不在赘述了。 下图,画圈的部分,就是批量发送群邮件相关的字符串。字符串提取其中,http://www.laohe788.com/zhuti.txt为邮件标题。 http://www.laohe788.com/zhengwen.txt为邮件内容这么多钓鱼软件,我简单分析了一下,稍微见证

  • ftp服务器的搭建

    结合这两个网址https://www.fenfa51.com/http://blog.sina.com.cn/s/blog_459ced7a0101ou76.html一:安装vsftpd查看是否已经安装vsftpdrpm-qa|grepvsftpd如果没有,就安装,并设置开机启动yum-yinstallvsftpdchkconfigvsftpdon二:基于虚拟用户的配置所谓虚拟用户就是没有使用真实的帐户,只是通过映射到真实帐户和设置权限的目的。虚拟用户不能登录CentOS系统。修改配置文件打开/etc/vsftpd/vsftpd.conf,做如下配置anonymous_enable=NO//设定不允许匿名访问local_enable=YES//设定本地用户可以访问。注:如使用虚拟宿主用户,在该项目设定为NO的情况下所有虚拟用户将无法访问chroot_list_enable=YES//使用户不能离开主目录ascii_upload_enable=YESascii_download_enable=YES//设定支持ASCII模式的上传和下载功能pam_service_name=vsftpd/

  • 测173个成年人的大脑的102个基因

    今天是大年初六,给大家带来的是测173个成年人的大脑的102个基因,希望你能学到知识。文章发表在NC,于2018年10月中旬,题目是:Highprevalenceoffocalandmulti-focalsomaticgeneticvariantsinthehumanbrain,测序数据都上传到了:https://www.ncbi.nlm.nih.gov/sra?term=SRP159015是开放下载的。研究者相信干细胞分裂过程中产生的somatic突变,是很多癌症的罪魁祸首。理论上大脑发育过程中的那些细胞分裂,也会伴随着同样的突变过程,所以呢,就会在局部富集一些somatic突变。然后作者假设那些somatic突变位点如果发生在已知的明确基因上,而且位点一致,具有germline病理性性突变效果。根据超高深度测序,研究团队发现并且证实了54个成年人的173个大脑区域的102个基因的确有一些somatic突变,包括DNMT3A和TET2这样可能起源于血液的突变。使用神经发育学的数学模型和近似贝叶斯推断理论,研究者预测,大片段的病理性的突变神经元是非常普遍的在人群中。背景介绍神经退行性疾

  • 数组计算

    /* 功能:数组计算 日期:2013-06-19 */ #include<stdio.h> #include<stdlib.h> intarraySum(intp[][8],intraw,intcol); intmain(void) { inta[8][8]={{1,1,1,1,1,1,1,1}, {1,1,0,0,1,0,0,1}, {1,0,0,1,0,0,1,1}, {1,1,1,0,0,1,0,1}, {1,0,1,1,1,0,0,1}, {1,1,0,0,0,1,1,1}, {1,1,1,1,0,0,0,1}, {1,1,1,1,1,1,1,1}}; arraySum(a,8,8); system("pause"); return0; } /************************************************************************ 函数名:arraySum 功能:数组计算 参数:intp[][8]数组 intraw数组的行 intcol数组的列

  • 【职场招聘】工程师:你不知道的Google面试游戏规则

    Google面试规则一:Google对于所有人(或者说绝大多数人)的面试都是非常类似的。不论你是名校教授,或者几十年工作经验,或者高中没毕业,面试Google的时候问的问题都很相似。很多人都会有自己擅长的领域,但是这个领域一般来说在onsite面试的时候会在5个面试官里面有1个人来问你,而电面的时候不会有人问。这点其实是很多人知道而不愿意相信的----很多人都会觉得自己非常special,Google应该会在乎我的特长吧。事实是Google面试几乎不考虑特长,而是在确定进公司之后根据特长分配project。 Google面试规则二: Google面试不会直接考难题。Google无论是电面还是onsite,一定会先问简单题。这不是坑你,而是为了让面试有区分度。之前的回答也有人提到----而且还有人专门提到怎么坑人时说到----真要坑人就上来出难题就是了,面对一个我一点不认识的人,出道题把他黑成白卷我觉得六七成的概率总是有的,要是我知道这个人的简历,黑成白卷基本就是百分之百了----二维DP会么,计算几何会么,数论会么?哦,算法都会了?大数据会么,lock-free会么,OS内核会么?总之

  • idea、pycharm 右下角不显示git分支及编码等问题

    让idea右下角显示git分支和文档编码状态 菜单栏中设置,View->StatusBar勾选即可 出自 活在当下,从零出发

  • 希尔排序

      概要 本章介绍排序算法中的希尔排序。内容包括:1. 希尔排序介绍2. 希尔排序图文说明3. 希尔排序的时间复杂度和稳定性4. 希尔排序实现4.1 希尔排序C实现4.2 希尔排序C++实现4.3 希尔排序Java实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3597597.html 更多内容:数据结构与算法系列目录   希尔排序介绍 希尔排序(ShellSort)是插入排序的一种,它是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有

  • regex

    C++11regex 这是codeforces75B的代码 #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cstring> #include<map> #include<set> #include<regex> usingnamespacestd; map<string,int>score; set<string>nameList; stringme,temp,name[1000]; typedeftuple<int,string>pr; prcareList[1000]; intn,cnt=1; voidcheck_and_add(stringtemp){ if(nameList.find(temp)==nameList.end()){ nameList.insert(temp); name[cnt++]=temp; } }

  • 作业抄袭简单检测

     最近带了电子工程实践一门课程,需要各位同学上交作业,这种实践课程作业相互抄袭一向常见,如果是抄袭也还好,由于交的是电子版,最可恶的就是拿别人的文件改了下名字就变成自己的,识别方法有很多,最简单的方法就是看修改时间和文件大小。 如下图所示,不同人的作业,修改时间、文件大小完全相同,正常情况下这是不可能发生的事情。(图中涉及姓名均以做处理)所以这种情况基本可以判断这些文件是否相同了,但是单纯从这一点判断还很难说明问题,还需要更严谨的方法。 更严谨一点的就是比对SHA1和MD5值。 MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被"篡改"。举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的"抵赖",这就是所谓的数字签名应用。也就是说MD5可以作为判断两个文件是否相同的重要标准。如果两个文

  • dns server 域名解析总结

      1、客户有两种使用公网域名解析的方法,一种是,直接配置A记录,将域名直接解析到ip地址。第二种是,配置NS记录,将对这个域名的解析分配给另外一个域名服务器,这个域名服务器就是客户自己搭建的内部域名服务器(在linux服务器上安装bind9软件)。   添加A记录的方法:   添加NS记录的方法: 另外,再添加一条A记录,将client.com指向一个ip地址。或者这个client.com是一个知名的dns服务商的ip地址,那么,需要在该dns服务商的A记录中增加指向客户真实的dnsserver的A记录。   问题:直接使用A记录就可以了,为何还需要NS记录呢?  A记录和NS记录的区别是,A记录直接给出目的IP,NS记录将DNS解析任务交给特定的服务器,NS记录中记录的IP即为该特定服务器的IP地址。   问题:在windows系统中看到的DNS缓存中的TTL时间是如何决定的? 解答:由两个模块公共决定的,一个是windows操作系统默认的域名TTL时间,一个是接收到的DNS报文中的TTL时间,取二者的较小值。 win

  • 海豚调度DolphinScheduler源码分析(一)

    系统架构设计 在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词 1.名词解释 DAG: 全称DirectedAcyclicGraph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图: dag示例 流程定义:通过拖拽任务节点并建立任务节点的关联所形成的可视化DAG 流程实例:流程实例是流程定义的实例化,可以通过手动启动或定时调度生成,流程定义每运行一次,产生一个流程实例 任务实例:任务实例是流程定义中任务节点的实例化,标识着具体的任务执行状态 任务类型:目前支持有SHELL、SQL、SUB_PROCESS(子流程)、PROCEDURE、MR、SPARK、PYTHON、DEPENDENT(依赖),同时计划支持动态插件扩展,注意:其中子 SUB_PROCESS 也是一个单独的流程定义,是可以单独启动执行的 调度方式: 系统支持基于cron表达式的定时调度和手动调度。命令类型支持:启动工作流、从当前节点开始执行、恢复被容错的工作流、恢复暂停流程、从失败节点开始

  • 数据结构学习--单循环链表(python)

    概念 将单链表的终端节点的指针由原来的空指针改为指向头节点,就是整个单链表形成一个环,这种首尾相接的单链表称为单循环链表. 实现 classNode: """ 节点 """ def__init__(self,value): self.data=value self.next=None classCircularLinkedList: def__init__(self): self.rear=None#尾节点 defis_empty(self): returnself.rearisNone #defappend(self,elem): #""" #尾插法 #""" #temp=Node(elem) #ifself.rearisNone: #temp.next=temp #self.rear=temp #else: #temp.next=self.rear.next #self.rear.next=temp #self.rear=temp defprepend(self,elem): """ 头插法 """ temp=Node(elem) ifself.rearisNone:

  • 【BZOJ2440&amp;&amp;2986】完全平方数

    题意:求第k个无平方因子数是多少 无平方因子数(square-freenumber),即质因数分解之后所有质因数的次数都为1的数 膜拜Po姐姐 二分答案设二分后值为x我们考虑前x个数中是否含有超过k个不是平方因子的数 我们考虑平方因子一定含有至少一个质数的平方  那么考虑容斥,即质数平方个数为0的数的个数-质数平方个数为1的数的个数+质数平方个数为2的数的个数-…… 公式表示的话设有p个素数而且选择了i个素数是平方,且任选i个素数的乘积为d,得到公式 $f(x)=\sum_{i=0}^{p}(-1)^i\lfloor\frac{n}{d^{2}} \rfloor(d为任意i个素数相乘的积)$ 发现d最多选择到$\sqrt{n}$那么我们可以考虑直接枚举d于是问题变成了如何快速判断d的贡献 莫比乌斯函数即是。 然后根据莫比乌斯函数的定义式,将式子化为$f(x)=\sum_{d=1}^{\sqrt{x}}\mu(d) \lfloor\frac{n}{d^{2}}\rfloor$ 所以我们枚举根号n内的所有答案带入计算即可复杂度$O(\sqrt{n}log{n}

  • 又结束了段繁忙期,来聊聊Null和Undefined吧

    前言: 我们经常会遇到这两位特殊的数据类型,比如查一个对象的属性时,如果这个对象没有这个属性就会报undefined(原型链)。又比如我们可以将一个对象置为null,就可以释放这个对象的引用,以便浏览器回收。那为什么会出现这些情况呢,下面让我们去了解下这两种数据类型吧。 一、Undefined类型是什么 Undefined类型只有一个值那就是undefined。在使用var来定义一个变量而未赋值时,这个变量的值就是undefined。(摘自Javascript高级程序设计) 让我们来验证下这句话。 varmsg; console.log(msg===undefined);复制 浏览器运行的结果自然是true。除了这种方法来证明它是undefined之外还有别的办法吗?当然还有,我们可以借助typeof操作符。 varmsg; console.log(typeofmsg);复制 返回的结果是’undefined‘。自然也可以帮助我们来识别。 我们经常会调用一个函数并传入参数,如果传的参数少于形参数量,多的形参其实值都为undefined。 functionfun(a,b,c){

  • 十万以内的所有素数

    这里主要是要考虑效率问题,在数据规模较大时,如果不考虑算法优化,效率将会非常差。 importtime #将特殊质数2事先放在列表中 t=[2] t0=time.time() count=1 #去掉所有偶数,从3开始迭代,步进为2 forxinrange(3,100000,2): #所有大于10的质数中,个位数只有1、3、7、9,大于5且以5结尾的整数能被5整除,这里首先过滤掉大于5且以5结尾的整数 ifx>5andx%10==5: continue #除去2之外,质数的因子中肯定是没有2的,这里去掉所有被除数中的偶数 #一个整数的前后对应的两个因子的乘积等于这个整数,所以一个整数如果平方根之前有一个因子,那平方根之后肯定有一个对应的因子,中间是平方根 #这里使用平方根极大减小了数据规模,以及减少了大量迭代次数 foriinrange(3,int(x**0.5)+1,2): ifx%i==0: break #要格外注意一下这里的else语句的执行逻辑 #没有进入for循环、以及for循环正常结束都会执行else语句,如果被break中断,else不会执行 else: count

相关推荐

推荐阅读