百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

PHP性能全面优化-值得收藏(php优化网站性能)

wxin55 2024-10-28 20:27 11 浏览 0 评论

0 前言

这篇文章算是对这本书的一点笔记 《高性能PHP应用开发》 目录大概都是搬过来的,但是有些技术是2011-11(出版日期)之前的,还有有些地方跟我的技术栈有所区别,就略过了。 比如Apache(我用的是nginx),比如memcached(我用的是redis),这些就略过了。

1. 基准测试技术

1.0 PHP技术栈

image.png

1.1 定义请求/响应声明周期

image.png

1.2 Apache Benchmark (ab工具)

  • 查看测试结果
    image.png
  • 常用选项
n: 要模拟的请求数;
c: 要模拟的并发请求数;
t: 执行模拟所需要的时间

1.3 Siege

Siege可以模拟托管文档的用户流量,与ab不同的是,Siege可以对文本文件中指定的URL列表运行负载测试。它还可以在执行其它请求之前让某个请求休眠,从而让你感觉某个用户在转移到Web应用程序的下一个文档之前正在读取该文档。

  • 分析结果
    image.png
  • 测试指标
    image.png
  • 常用参数
-c 200 指定并发数200
-r 5 指定测试的次数5
-f urls.txt 制定url的文件
-i internet系统,随机发送url
-b 请求无需等待 delay=0
-t 5 持续测试5分钟 [H,M,S--时分秒,默认M]
-r和-t一般不同时使用

1.4 影响基准测试数字

  • 地理位置和网络问题
  • 响应大小
  • 代码处理
  • 浏览器行为
  • Web服务配置

2.提高客户端下载和呈现性能

2.1 概述

  • 第一个工具集(Firebug、YSlow、Page Speed)可提供以下信息来帮助我分析响应:
  1. Web服务器发送的响应的细节信息;
  2. 分析JavaScript中的前端逻辑;
  3. 浏览器将读取的资源的逐项列表;
  4. 浏览器获取和接受资源所花费的时间;
  5. 对如何优化响应的建议
  • 第二个工具集(YUI Compressor、Closure Compiler和Smush.it)将帮助我们优化响应,简言之,我们可以使用这些工具压缩JavaScript、CSS文件以及网页所需的图像。

2.2 Firebug

好吧,我没用过,个人觉得Chrome自带的就够用了


image.png


还可以看时间花费细节:


image.png

2.3 YSlow

优化规则:

2.3.1 CSS优化

  • 将CSS样式放置在HTML文档顶部;
  • 避免某种CSS表达式;
  • 精简CSS文件

2.3.2 图像优化

  • 使用所要求的图像大小,而不是在HTML使用高度和宽度重新调整图像尺寸;
  • 在可能的情况下创建子画面

2.3.3 JavaScript优化

  • 将JavaScript放置在HTML底部;
  • 精简JavaScript
  • 将JavaScript做成外部文件
    ####### 2.3.4 服务器优化
  • 服务器是否采用Gzip/bzip2压缩
  • DNS查找是否有所减少
  • 是否实现了Etag

2.4 YUI Compressor和Closure Compiler

这两个是JavaScript精简工具 现在不都是用gulp和webpack了吗?

2.5 图像压缩

使用Smush.it工具

3. PHP代码优化

3.1 PHP最佳实践

一些小tips

  • ehco时用逗号连接比点连接更优;
  • require优于require_once:require_once需要统计引入文件的引用次数
  • for、foreach和while循环范围数组:foreach性能最好
  • fread()、file_get_contents()、file()和readfile()。file_get_contents()、readfile()、fread()以字符串返回数据,而file()则将文件中的数据作为数组返回,每一行是数组的一个元素。四个方法都可以读取文件内容,但只有file_get_contents()将文件缓存到内存中,以便更快地进行读写操作,这种方式称为内存映射。
    image.png

3.2 使用VLD、strace和Xdebug一探究竟

  • 用VLD查看Opcode函数
pecl install channel://pecl.php.net/vld-0.14.0 安装

测试代码

<?php
echo 'hello' , 'World!';

执行

php -dvld.active=1 test.php

结果

Finding entry points
Branch analysis from position: 0
Jump found. (Code = 62) Position 1 = -2
filename:       /apps/www/test/test.php
function name:  (null)
number of ops:  5
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT                                                 
         1        ECHO                                                     'hello'
         2        EXT_STMT                                                 
         3        ECHO                                                     'World%21'
   3     4      > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     4; out1:  -2
path #1: 0, 
helloWorld!
  • 使用strace进行C级跟踪(可以在Apache请求跟踪所调用的C函数,我玩的是nginx这部分跳过)

3.3 发现瓶颈

  1. Xdebug是面向PHP的调试器和概要分析工具,除了更多的调试信息外,Xdebug还可以为开发人员提供如下的信息:
  • PHP脚本的内存消耗;
  • 对某个函数执行的调用总数;
  • 函数内部花费的总时间;
  • 某个函数的完整栈跟踪;
  1. 举例
  • 断点调试:
    image.png
    环境配置点这里 phpstrom+wampserver+xdebug配置
  • 性能分析(可以用phpstorm分析xdebug生成的cachegrind.out日志):
    image.png
    分析结果:
    image.png
  • 行为追踪【其实就是代替断点单步打日志】
    示范代码:
xdebug_start_trace('/tmp/trace', XDEBUG_TRACE_APPEND ); //开始,日志写到/tmp/trace文件
class Node {
    public $val; //值
    public $d; //距离
    public $p; //父节点
    public $linkedNodes = [];//连接的顶点
    public function __construct($val)
    {
        $this->val = $val;
    }
}


/**
 * Dijkstra
 **/
class DijkstraAlgorithm
{
    /**
     * 生成图
     * @param array $vertex
     * @return array
     */
    public function buildGraph($vertex)
    {
        $graph = [];
        $nodes = array_keys($vertex);
        foreach ($nodes as $node) {
            $graph[$node] = new Node($node);
        }
        foreach ($vertex as $key => $item) {
            foreach ($item as $value) {
                if (isset($graph[$value])) {
                    $graph[$key]->linkedNodes[] = $graph[$value];
                }
            }
        }
        return $graph;
    }

    /**
     * 初始化操作
     * @param array $graphNodes
     * @param Node $s
     */
    public function init(&$graphNodes, &$s)
    {
        foreach ($graphNodes as $graphNode) {
            $graphNode->d = 9999999;
        }
        $s->d = 0;
    }

    /**
     * 松弛操作
     * @param Node $u
     * @param Node $v
     * @param Array $w
     * @return bool
     */
    public function relax(&$u, &$v, $w)
    {
        $d = $u->d + $w[$u->val . '_' . $v->val];
        if($v->d > $d) {
            $v->d = $d;
            $v->p = $u;
            return true;
        }
        return false;
    }

    /**
     * 从队列取出最小距离的顶点
     * @param array $queue
     */
    public function extractMin(&$queue)
    {
        $result = [];
        foreach ($queue as $item) {
            $result[$item->d] = $item;
        }
        ksort($result);
        $queue = array_values($result);
        return array_shift($queue);
    }

    /**
     * Dijkstra 算法
     * 问题1:没考虑到负环路
     * @param $graphNodes
     * @param $s
     */
    public function dijkstra(&$graphNodes, $s, $w)
    {
        $this->init($graphNodes, $s);
        $gather = [];
        $queue = $graphNodes;
        while (!empty($queue)) {
            $node = $this->extractMin($queue);
            $gather[] = $node;
            foreach ($node->linkedNodes as $linkedNode) {
                if($this->relax($node, $linkedNode, $w)) {
                    if(!in_array($linkedNode, $queue)) {
                        array_push($queue, $linkedNode);
                    }
                }
            }
        }
    }
}


//顶点
$vertex = [
    'a' => ['b', 'c'],
    'b' => ['d'],
    'd' => ['e'],
    'c' => ['e'],
    'e' => [],
];
//边的权重
$w = [
    'a_b' => 1,
    'a_c' => 3,
    'b_d' => 2,
    'd_e' => 2,
    'c_e' => 4,
];

$g = new DijkstraAlgorithm();
$graphNodes = $g->buildGraph($vertex);
$g->dijkstra($graphNodes, $graphNodes['a'], $w);

$w = [
    'a_b' => 1,
    'a_c' => 3,
    'b_d' => 2,
    'd_e' => 2,
    'c_e' => 4,
];
xdebug_stop_trace();//结束行为追踪

centos的php.ini配置:

[xdebug]
zend_extension="/apps/install/php/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so"
xdebug.remote_enable = 1
xdebug.trace_format = 1
xdebug.auto_trace = 0
xdebug.trace_output_dir = /tmp/
xdebug.trace_output_name = trace.%c.%p

xdebug.collect_params = 4
xdebug.collect_includes = On
xdebug.collect_return = On
xdebug.show_mem_delta = On
xdebug.var_display_max_depth = 2

分析结果

image.png


以上看起来不是很清晰,可以借助这个PHP进行分析:
用法:


usage:
        php run-cli tracefile [sortkey] [elements]

Allowed sortkeys:
        calls, time-inclusive, memory-inclusive, time-own, memory-own //后四个分别指包含子方法的耗时, 包含子方法的内存消耗,自己方法的耗时,自己方法体的内存消耗

示例:

php tracefile-analyser.php trace.log.xt time-inclusive 20 //获取最耗时的20个方法

结果:

Showing the 20 most costly calls sorted by 'time-inclusive'.

                                                                                                         Inclusive        Own
function                                                                                         #calls  time     memory  time     memory
-----------------------------------------------------------------------------------------------------------------------------------------
                                                                                                      1  5.8553 12017136  5.8553 12017136
common\services\qmyx\BuildingInfoService->getBuildingList                                             1  1.7179  3559752  0.0038  -457592
common\repositories\qmyx\MyParamValueRepository->getParamOptionByScopeIdAndValueAndParamCode         45  1.3890   914592  0.0126  -275240
yii\db\ActiveQuery->one                                                                              46  1.3441  1012584  0.0062      704
yii\db\Query->one                                                                                    46  1.2831   951440  0.0055  -323104
yii\db\Command->queryInternal                                                                        52  1.1350  1326664  0.0155     3504
yii\db\Command->queryOne                                                                             47  0.9962  1061744  0.0038        0
PDOStatement->execute                                                                                52  0.8573   634848  0.8573   634848
yii\db\ActiveQuery->createCommand                                                                    50  0.3639   268176  0.0090   -56976
yii\db\QueryBuilder->build                                                                           50  0.2823    78424  0.0150  -133952
yii\db\QueryBuilder->buildCondition                                                                 295  0.1507    32400  0.0082    10392
yii\db\QueryBuilder->buildWhere                                                                      50  0.1488    27376  0.0025      224
yii\BaseYii::createObject                                                                            73  0.1318  5219896  0.0062        0
yii\db\QueryBuilder->buildAndCondition                                                               92  0.1316    22928  0.0060    -8896
yii\db\Command->queryAll                                                                              4  0.1239   247608  0.0002        0
yii\di\Container->get                                                                                75  0.1239  5219896  0.0051        0
yii\di\Container->build                                                                              75  0.1189  5219896  0.0083    18056
yii\log\Logger->log                                                                                 156  0.1131   739152  0.0470 -2074992
ReflectionClass->newInstanceArgs                                                                     75  0.1009  5022912  0.0037    99568
common\services\project\ProjectService->filterDisabledProjectIdsByAppCode                             1  0.0961   596344  0.0003    -4880

4. Opacode缓存

4.1 回顾路线图

image.png

4.2 PHP的生命周期

image.png

在此补充一下,php7新加了语法解析树。

应用了Opcode缓存的PHP生命周期:


image.png

4.2 Opcode缓存工具

  • Alternative PHP Cache(APC)
  • XCache
  • eAccelerator

现在用opcache啦~~ 有兴趣看看鸟哥这篇文章 让PHP7达到最高性能的几个Tips

5. 变量缓存

image.png


缓存可以用memcached或者redis等中间件。

6. 选择正确的Web服务器

并发当然是选择nginx

7. 优化Web服务器和内容交付

大部分是针对Apache的优化,略过。 还有负载均衡、共享会话、分布式架构的一些问题(缓存一致性、缓存版本等等)、监控应用程序Ganglia、Cacti、Nagios。

8. 数据库优化

  • MySQL的MyISAM的优缺点:
    image.png
  • InnoDB的优缺点:
    image.png
  • 选择存储引擎
    1.当应用程序执行的大部分是读取操作时(95%)--MyISAM; 当事务性和一致性非常重要时---InnoDB; 当你有一个包含很多连接表的复杂模式时---InnoDB; 当不间断操作非常重要时---InnoDB(因为MyISAM没用防止数据崩溃的日志、版本控制和记录功能)
  • 了解MySQL如何使用内存
    MySQL对内存来者不拒,你给它的内存越多,它的性能就越好,直到达到某个点。这个点就是MySQL的速度超过数据“工作集”的速度,超过这个点之后,无论你再为它分配多少内存,它的性能几乎都不会再有提高。

“工作集”就是经常使用的数据集,如果这个数据集可以轻松地放到内存中,性能的提高也基本上就到了极限,特别是当拥有一个好的索引集时。

  • InnoDB与MyISAM内存使用的比较 MySQL配置文件提供了很多指令,可用于控制服务器的内存占用。分为下面几大类: 1.影响缓冲区和缓存大小的指令,适用所有存储引擎; 2.仅影响MyISAM存储引擎的指令; 3.仅影响InnoDB存储引擎的指令,通常以“innodb_”开头; 4.控制各种资源(如连接数量等)限制的指令; 定义属性(如字符集、路径等)的指令。
  • 每服务器和每连接(线程)内存使用的比较 必须记住,当在配置文件中配置内存缓冲区和缓存的大小时,一些内存结构是按照每个 连接或每个连接来分配的。当连接到MySQL的连接数增加时,MySQL将使用更多的内 存,因此一定要从应用程序连接到数据库服务器打开的连接数减至最少,这一点非常重 要。MySQL可以使用的最大内存定义如下:
    image.png
  • 查找配置文件
    image.png
  • Mysqltuner.pl: 优化数据库服务器的内存

1). top监控进程

![image.png](https://upload-images.jianshu.io/upload_images/3596546-d9b99687b1416f6f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2). iostat查看I/O性能

image.png

选项 说明


image.png

  1. 若 %iowait 的值过高,表示硬盘存在I/O瓶颈
  2. 若 %idle 的值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量
  3. 若 %idle 的值持续低于1,则系统的CPU处理能力相对较低,表明系统中最需要解决的资源是 CPU
    image.png

3).Mysqltuner.pl

当你看到较高的%util或%iowait值,那么应该查看驱动器的性能,或者看看打开的一些MySQL内存缓冲区以减少MySQL服务器命中磁盘所需的时间。但该系统没有显示I/O性能的任何问题,因此我们可以继续进行。 Mysqltuner.pl可以减轻配置和检查数据服务器的大量工作。



  • 示例可能出现的问题:

image.png

  • 附上MySQL的常用命令和设置
-- show variables like '%max_connections%'; 查看最大连接数


set global max_connections=1000 重新设置



mysql> show status like 'Threads%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 58    |
| Threads_connected | 57    |   ###这个数值指的是打开的连接数
| Threads_created   | 3676  |
| Threads_running   | 4     |   ###这个数值指的是激活的连接数,这个数值一般远低于connected数值
+-------------------+-------+
 
Threads_connected 跟show processlist结果相同,表示当前连接数。准确的来说,Threads_running是代表当前并发数
 
这是是查询数据库当前设置的最大连接数
mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 1000  |
+-----------------+-------+
 
可以在/etc/my.cnf里面设置数据库的最大连接数
[mysqld]
max_connections = 1000
****命**令: show processlist;** 
**如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接。** 
**show processlist;****只列出前100条,如果想全列出请使用****show full processlist;** 
[MySQL](http://lib.csdn.net/base/14 "MySQL知识库")> show processlist;

**命令: show status;**

**命令:show status like '%下面变量%';**

Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。 
Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。 
Connections 试图连接MySQL服务器的次数。 
Created_tmp_tables 当执行语句时,已经被创造了的隐含临时表的数量。 
Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。 
Delayed_writes 用INSERT DELAYED写入的行数。 
Delayed_errors 用INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。 
Flush_commands 执行FLUSH命令的次数。 
Handler_delete 请求从一张表中删除行的次数。 
Handler_read_first 请求读入表中第一行的次数。 
Handler_read_key 请求数字基于键读行。 
Handler_read_next 请求读入基于一个键的一行的次数。 
Handler_read_rnd 请求读入基于一个固定位置的一行的次数。 
Handler_update 请求更新表中一行的次数。 
Handler_write 请求向表中插入一行的次数。 
Key_blocks_used 用于关键字缓存的块的数量。 
Key_read_requests 请求从缓存读入一个键值的次数。 
Key_reads 从磁盘物理读入一个键值的次数。 
Key_write_requests 请求将一个关键字块写入缓存次数。 
Key_writes 将一个键值块物理写入磁盘的次数。 
Max_used_connections 同时使用的连接的最大数目。 
Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。 
Not_flushed_delayed_rows 在INSERT DELAY队列中等待写入的行的数量。 
Open_tables 打开表的数量。 
Open_files 打开文件的数量。 
Open_streams 打开流的数量(主要用于日志记载) 
Opened_tables 已经打开的表的数量。 
Questions 发往服务器的查询的数量。 
Slow_queries 要花超过long_query_time时间的查询数量。 
Threads_connected 当前打开的连接的数量。 
Threads_running 不在睡眠的线程数量。 
Uptime 服务器工作了多少秒。

My.ini配置 虚拟内存

[](http://www.pc51.net/data/MySQL/2007-01-04/2551.html)

innodb_buffer_pool_size=576M   ->128M InnoDB引擎缓冲区

query_cache_size=100M             ->32 查询缓存
tmp_table_size=102M                  ->32M 临时表大小
key_buffer_size=16m                  ->8M

**设置max_connections**

**命令:show variables like '%max_connections%'** (这个办法在debian+mysql  Ver 12.22 Distrib 4.0.22, for pc-[Linux](http://lib.csdn.net/base/linux "Linux知识库") (i386)
里实验了)
设置办法是在my.cnf文件中,添加下面的最后红色的一行:

--------------------------------------------------------------------------------

[mysqld] 
port=3306 
#socket=MySQL 
skip-locking 
set-variable = key_buffer=16K 
set-variable = max_allowed_packet=1M 
set-variable = thread_stack=64K 
set-variable = table_cache=4 
set-variable = sort_buffer=64K 
set-variable = net_buffer_length=2K 
set-variable = max_connections=32000 
(在院里的DELL机器mysql4.0里的语法不同
max_connecionts=2000
直接这么写就好了

)

--------------------------------------------------------------------------------

修改完毕后,重启MySQL即可。当然,为了确保设置正确,应该查看一下max_connections。

注意: 
1、虽然这里写的32000。但实际MySQL服务器允许的最大连接数16384; 
2、除max_connections外,上述其他配置应该根据你们系统自身需要进行配置,不必拘泥; 
3、添加了最大允许连接数,对系统消耗增加不大。 
4、如果你的mysql用的是my.ini作配置文件,设置类似,但设置的格式要稍作变通。

用mysqld --help 可以查看到max_connections 变量。 
或者 mysql -uuser -p
**后mysql>show variables;
也会看到max_connections 。   **

下面是修改张老师 的redhat9的方法:

先是mysql -uw01f -p
mysql>show variables;
看到max_connections 为100
mysql>exit;
vi /etc/my.cnf
    [mysqld]
set-variable=max_connections=250  #加入这些内容
:wq

/etc/init.d/mysqld restart
  • 优化InnoDB 1.innodb_file_per_table:InnoDB为每个数据库创建一个文件并用这个文件来管理数据库的表。这意味着如果表的大小先增大然后又缩小,则很难恢复磁盘空间。设置该选项将使每个表使用一个独立的数据存储文件。如果你想在现有数据库上更改此设置,应该备份该数据库,然后删除它,再更改选项,然后重新启动服务器,最后从备份中重新加载该数据库; 2.innodb_buffer_pool_size:如果你只使用InnoDB表,可以把这一项设置为可用内存的70%左右,如果混用MyISAM,则可以小一些; 3.innodb_log_buffer_size=4M:4M可以满足绝大部分记录的需求,而且提供了一个合理的性能; 4.innodb_log_file_size=256M:推荐值,可以在恢复数据库的速度与保持较高的运行时性能之间取得良好的平衡; 5.innodb_flush_log_at_trx_commit=2:这一项控制将日志文件刷新到磁盘的频率,如果你可以容忍在发生崩溃时丢失一些记录,那么可以把它的值设置为2来减少磁盘写入的数量、加快性能以及减少驱动器上的I/O负担。
  • 找到有问题的日志 查看慢查询日志,开启和如何查看就不说了,网上一搜铺天盖地的。
  • 分析有问题的查询 explain神器

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: