<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NotionNext BLOG</title>
        <link>https://notionext-three.vercel.app/</link>
        <description>这是一个由NotionNext生成的站点</description>
        <lastBuildDate>Tue, 24 Oct 2023 02:21:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2023, Aurora</copyright>
        <item>
            <title><![CDATA[大龄程序员的一些思考]]></title>
            <link>https://notionext-three.vercel.app/article/old-coder</link>
            <guid>https://notionext-three.vercel.app/article/old-coder</guid>
            <pubDate>Mon, 23 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[关于30岁以上程序员的一些思考]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-cbfa8404531d400e9a5b2e860f051d65"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-1f71ca63ed644a6a8df8f79310d8959f"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">从2014年本科毕业，15年进入互联网开始，入行已有8年了，踩了很多坑，也积累了一些经验，目前还在摸索中，希望从不确定中寻找属于自己的确定性</div></div><div class="notion-blank notion-block-86634da909c949d4a04644caf6d0eb78"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-bc4863db750544209d0e661376a84f9a" data-id="bc4863db750544209d0e661376a84f9a"><span><div id="bc4863db750544209d0e661376a84f9a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bc4863db750544209d0e661376a84f9a" title="确保身心健康"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">确保身心健康</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9f0edc0b281641a89a085882d795c1c6" data-id="9f0edc0b281641a89a085882d795c1c6"><span><div id="9f0edc0b281641a89a085882d795c1c6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9f0edc0b281641a89a085882d795c1c6" title="身体健康"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">身体健康</span></span></h4><div class="notion-text notion-block-fbe74ae60c79495caffe17ba399ac7cc">众所周知，身体是革命本钱，身体是银行卡前面那个1，其他的物质都是后面的0，没有了这个1其他都没有价值。而且程序员长期坐在电脑前，非常容易引发眼睛，腰椎，颈椎等器官的问题，所以保证运动必不可少，<b>建议每周至少保证一次高强度的运动，例如跑步，打球，健身等，其中健身里面的撸铁对肩颈问题有很好的缓解作用（本人以前有很严重的肩颈问题，后面通过坚持健身极大的缓解了这个问题）</b></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2878283b5cf6418f8caf3c6b98de0de3" data-id="2878283b5cf6418f8caf3c6b98de0de3"><span><div id="2878283b5cf6418f8caf3c6b98de0de3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2878283b5cf6418f8caf3c6b98de0de3" title="心理健康"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">心理健康</span></span></h4><div class="notion-text notion-block-824f820232cb40a6afee1dcc5755bf76">心理健康包含多方面的，随着年龄的增长，被焦虑的问题越来越多，学业，工作，结婚，家庭，亲子，中年危机等等。正所谓，在国内，可能没有那个年龄段时轻松的，焦虑从小学开始，个人经验能有效缓解焦虑的几种方式</div><ul class="notion-list notion-list-disc notion-block-c6bbdee4fa904c2d8263a0bc01bc519f"><li>读书：各种类型的，只要是自己感兴趣的正能量的都可以</li></ul><ul class="notion-list notion-list-disc notion-block-5501be3f77fe478ebc9f313703f402c9"><li>运动：运动出汗能产生多巴胺，不仅能促进身体健康，还能促进心理健康，简直完美</li></ul><ul class="notion-list notion-list-disc notion-block-7054bed030754011bdda9c53ea111bdb"><li>沟通：经常跟自己要好的朋友聊天谈心，跟大佬聊天，学习过来人经验也能有效缓解焦虑</li></ul><ul class="notion-list notion-list-disc notion-block-9f23ef8eebf04a42b5ecb9a18994107e"><li>爱好：如果能培养一个除了工作之外的爱好就更好了，比如下棋，打球，画画，唱歌等等，之前在北京的时候，有骑摩托的爱好，那会每到周末，约两个好友一起出去跑跑，感觉不要太爽</li></ul><div class="notion-blank notion-block-060d85bbb70f44978a71bb0fbaf6c908"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-7f81a849127c4b6fab4e844b9488a834" data-id="7f81a849127c4b6fab4e844b9488a834"><span><div id="7f81a849127c4b6fab4e844b9488a834" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7f81a849127c4b6fab4e844b9488a834" title="成为技术专家or管理？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>成为技术专家or管理？</b></span></span></h3><div class="notion-text notion-block-e19a524259654c30a056f8d865c2396b">TODO…</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-50310dbf414745e0a0aaebcdb06c6700" data-id="50310dbf414745e0a0aaebcdb06c6700"><span><div id="50310dbf414745e0a0aaebcdb06c6700" class="notion-header-anchor"></div><a class="notion-hash-link" href="#50310dbf414745e0a0aaebcdb06c6700" title="远程remote？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">远程remote？</span></span></h3><div class="notion-text notion-block-17f5279b5b3546ceb2e3b7f69bd6fa3b">看到有一些大佬在年龄大了后在家做远程工作，这里应该分成两种remote，一种是国内的，一种国外的</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-eb08ca72fda04057ba609332ad851eb0" data-id="eb08ca72fda04057ba609332ad851eb0"><span><div id="eb08ca72fda04057ba609332ad851eb0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#eb08ca72fda04057ba609332ad851eb0" title="国内remote:"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">国内remote:</span></span></h4><ul class="notion-list notion-list-disc notion-block-5ab48101daab4514b3d4d9542143637b"><li>可能岗位相对少点，理论上除了收入低一点，其他应该跟坐班区别不大，经历过疫情那会远程办公的同学应该深有体会</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-42523378de4d48eaba22b9a361ab7e54" data-id="42523378de4d48eaba22b9a361ab7e54"><span><div id="42523378de4d48eaba22b9a361ab7e54" class="notion-header-anchor"></div><a class="notion-hash-link" href="#42523378de4d48eaba22b9a361ab7e54" title="国外remote："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">国外remote：</span></span></h4><ul class="notion-list notion-list-disc notion-block-2a4b6029544b40a49b3ea58d33b506bd"><li>据我了解，国外的岗位相对多一点，</li></ul><ul class="notion-list notion-list-disc notion-block-ae1ab9287a3d4a9db1811e6e6c850273"><li>语言，这点对于英语不好的同学非常致命，除了面试要用英语外，平时沟通也基本都是英语，假如能跨过这道坎，相信其他都不是问题</li></ul><ul class="notion-list notion-list-disc notion-block-e337f07474eb4393a8b9734b92ea7881"><li>时差，国外remote一般都是有时差的，近点的国家还好，太远的国家，基本是晚上对应白天，所以可能会有经常需要熬夜的情况</li></ul><div class="notion-blank notion-block-2db5a86549be424d83a92e1475da8b2e"> </div><div class="notion-blank notion-block-6a775dcbc1544828be5814751e3928df"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-71a24e80ea444fd0af5402cda94ef281" data-id="71a24e80ea444fd0af5402cda94ef281"><span><div id="71a24e80ea444fd0af5402cda94ef281" class="notion-header-anchor"></div><a class="notion-hash-link" href="#71a24e80ea444fd0af5402cda94ef281" title="寻找副业"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">寻找副业</span></span></h3><div class="notion-text notion-block-7c83e7c815924285bf3355c50c3a6dd4">程序员可以选择的副业有很多种，以下是一些建议：</div><ul class="notion-list notion-list-disc notion-block-d1868253366b4397bb74c14afd403e52"><li><b>写作</b>：撰写技术文章或教程，发布在博客、公众号、知乎等平台上，还有在掘金这种地方写小册。通过广告和付费阅读等方式，可以获得一定的收入。</li></ul><ul class="notion-list notion-list-disc notion-block-70976a2bdd164b6985d0be04266c313d"><li><b>创立个人品牌</b>：通过积累经验和作品，创立自己的个人品牌，提高个人影响力。这可以为你带来更多商业机会，如演讲、顾问、培训等。</li></ul><ul class="notion-list notion-list-disc notion-block-6776cb9dc6fb49e78e1bd4819fb41822"><li><b>接私活</b>：在业余时间为其他公司或个人完成项目，如网站开发、小程序、APP 等。你可以在一些平台（如猪八戒、实现网、码市等）上找到相关项目，或者通过朋友和同事介绍获得更多机会。</li></ul><ul class="notion-list notion-list-disc notion-block-00657d2691b44166887d3e853e893b2e"><li><b>做个人博客或开源项目</b>：通过分享自己的技术经验和心得，吸引更多人关注并建立个人品牌。这可以为你带来一些广告收入和合作机会。同时，参与开源项目可以提高你的技术水平，也有助于拓展人际关系。</li></ul><ul class="notion-list notion-list-disc notion-block-80b2cf21a64f46549896f8d38bff7afd"><li><b>网络兼职</b>：利用自己的技能在一些在线教育平台上教授前端课程，如慕课网、极客时间等。你还可以在一些问答平台（如知乎、Stack Overflow）上回答问题，帮助他人解决问题，提高自己的知名度。</li></ul><ul class="notion-list notion-list-disc notion-block-38d27e56cc6e464d90d8c7bd2cb26973"><li><b>开发移动应用(或者插件)</b>：如果你对移动开发有兴趣，可以尝试开发自己的应用，上架到应用商店。通过广告和内购等方式，你可以获得持续的收入。</li></ul><ul class="notion-list notion-list-disc notion-block-a027601ffd654b8aa31905e2e92836e0"><li><b>开发小游戏</b>：如果你对游戏开发有兴趣，可以尝试开发自己的小游戏，发布在微信小程序、抖音等平台上。通过广告和内购等方式，你可以获得持续的收入。</li></ul><div class="notion-text notion-block-9da047f212d7443f922a45cbcf7764e4">总之，程序员可以选择的副业方向很多，关键在于发掘自己的兴趣和优势，并付诸实践。同时，副业也需要长期坚持和投入，才能获得稳定的收益。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-e4f23f3c0f0b4e8bb2a37d9e5681de52" data-id="e4f23f3c0f0b4e8bb2a37d9e5681de52"><span><div id="e4f23f3c0f0b4e8bb2a37d9e5681de52" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e4f23f3c0f0b4e8bb2a37d9e5681de52" title="敢于创业"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>敢于创业</b></span></span></h3><div class="notion-text notion-block-6b0ea67d7e6d4a64a23968da703c5c82">程序员创业要闯三关：</div><ul class="notion-list notion-list-disc notion-block-d8a068142c5542f2a9a4427c7f7ff095"><li>首先是技术关，通常这是程序员最容易闯的一关，因为程序员创业肯定会找相对熟悉的领域去做。</li></ul><ul class="notion-list notion-list-disc notion-block-92f27de74f0f435fba315a281a1593e2"><li>其次业务观，有一定挑战。因为做 2C 要能获客，做 2B 要能搞定客户。逻辑思维能力也很重要，但不是全部。2C 比较适合逻辑思维能力，程序员背景的人肯定能搞得很明白。2B 获客更多是软技能，其中包括察言观色、判断对方角色、决策链决策逻辑等，并不是所有的程序员都能做得好。</li></ul><ul class="notion-list notion-list-disc notion-block-40d1da380ab445e98d2c81bf2cda220a"><li>最后是组织关。公司人很少的时候，20人以内每个人都认识，不太需要过多的管理机制。但如果公司到了 100 人甚至更多，组织能力没到，人越多效率越低，这是非常大的障碍。</li></ul><div class="notion-text notion-block-a490b64a46b240c88c408b591867d25c"><b>所以程序员除了固有的理性思维能力之外，还要能培养跟人打交道的能力，培养个人魅力，同时对组织管理要有敬畏之心。</b></div><div class="notion-blank notion-block-01e17fb9975b4c5b9c86e70af10bc6c0"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-070a4bbd552b4ac8b0102b29d423b079" data-id="070a4bbd552b4ac8b0102b29d423b079"><span><div id="070a4bbd552b4ac8b0102b29d423b079" class="notion-header-anchor"></div><a class="notion-hash-link" href="#070a4bbd552b4ac8b0102b29d423b079" title="Task"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Task</span></span></h3><div class="notion-text notion-block-4403b007ff0748b0b43a750de83d9fbc">强行给自己立几个flag</div><div class="notion-to-do notion-block-19700240d33b4b18b41914b3d7893885"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-unchecked"></div></span><div class="notion-to-do-body">每周至少来一次高强度运动</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-c32ff4b356da4c338156cd0b25a38d1f"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-unchecked"></div></span><div class="notion-to-do-body">每月至少开启读一本书（本来想每周，但是感觉有点难实现）</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-94f6e1b8c4f44988a30395631eff01d4"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-unchecked"></div></span><div class="notion-to-do-body">每月写一篇博客</div></div><div class="notion-to-do-children"></div></div><div class="notion-blank notion-block-059662f5078744998d5a15ccd2d43935"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-dd0253799e8a4a24881845487d44c2ad" data-id="dd0253799e8a4a24881845487d44c2ad"><span><div id="dd0253799e8a4a24881845487d44c2ad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dd0253799e8a4a24881845487d44c2ad" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h3><ul class="notion-list notion-list-disc notion-block-da5e6875567d42a3a357a3a962910f9a"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/post/7291936473078775843">https://juejin.cn/post/7291936473078775843</a></li></ul><div class="notion-blank notion-block-c3b2d4c7db9c4936a1e3207f5b677c3b"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Nextjs开发相关资源汇总（建议收藏）]]></title>
            <link>https://notionext-three.vercel.app/article/tailwind</link>
            <guid>https://notionext-three.vercel.app/article/tailwind</guid>
            <pubDate>Thu, 19 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[使用Nextjs和Tailwind CSS 可能会用到的优质资源]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-e88d2b4c49d14ea29688359c8590d802"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-6dbc9704026c4f2cb092034c02f2c379"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">在使用Nextjs和Tailwind开发时可能会用到的三方优质资源和库（不定期更新）</div></div><div class="notion-blank notion-block-2768aa4fb43e47538e4bde5b066d6b35"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8562e20bf2f7446e92b9daae6f051af3" data-id="8562e20bf2f7446e92b9daae6f051af3"><span><div id="8562e20bf2f7446e92b9daae6f051af3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8562e20bf2f7446e92b9daae6f051af3" title="📝 官方文档"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 官方文档</span></span></h2><div class="notion-text notion-block-9e84365d83fc4572ae5c94d1570708af"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://tailwindcss.com/">Tailwind官方文档网站</a></div><div class="notion-text notion-block-d89d8932e38c451f9a9401653358689d"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://nextjs.org/docs">Nextjs官方文档</a></div><div class="notion-callout notion-gray_background_co notion-block-2398fd98d5ad4836b6b4d211f0abccde"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">强烈建议看英文文档，中文文档更新的没有英文文档及时，且翻译水准良莠不齐</div></div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-2dec2f4e33d84689b363e92d8144f4ae" data-id="2dec2f4e33d84689b363e92d8144f4ae"><span><div id="2dec2f4e33d84689b363e92d8144f4ae" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2dec2f4e33d84689b363e92d8144f4ae" title="优质组件库（使用Tailwind）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">优质组件库（使用Tailwind）</span></span></h3><ul class="notion-list notion-list-disc notion-block-029cb7f016114d3dbaf62fd46b36cddd"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://headlessui.com/">headlessui</a>,TW官方组件库，现有组件比较精致，缺点是组件数量比较少</li></ul><ul class="notion-list notion-list-disc notion-block-536e54eff7a64b05819bd07293daf479"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://daisyui.com/">daisyui</a>，组件较多，设计风格比较欧美，有多个主题可选，适合landing页开发</li></ul><ul class="notion-list notion-list-disc notion-block-b1668c715cf54fe5a6c063c7b8f4cfc1"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ui.shadcn.com/">shadcn/ui</a>，组件较多，设计简洁，适合做后台系统，并且它可以单个组件安装，非常推荐</li></ul><ul class="notion-list notion-list-disc notion-block-dc51d35fec17455e8f7c57ca25d37e51"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.tremor.so/components">tremor/ui</a>，有不少chart组件，设计简洁漂亮，适合dashboard页面开发</li></ul><div class="notion-blank notion-block-9b6af56ab4d34c0ca0df21d858802d19"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d5f8b660868a4783a094755c6559b976" data-id="d5f8b660868a4783a094755c6559b976"><span><div id="d5f8b660868a4783a094755c6559b976" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d5f8b660868a4783a094755c6559b976" title="landing页优质模版（使用Tailwind）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">landing页优质模版（使用Tailwind）</span></span></h3><ul class="notion-list notion-list-disc notion-block-0b4e152502124ec288d1ded8863aaeeb"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://floatui.com/templates">floatui</a>，可用模版没那么多，但大部分免费，在免费里算设计精良的</li></ul><ul class="notion-list notion-list-disc notion-block-f15f03181e624437afaf4320e183744b"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://flowbite.com/">flowbite</a>，可用组件和模版较多，设计的也比较好看，但相当一部分是收费的</li></ul><ul class="notion-list notion-list-disc notion-block-83b7252eae314322a0a965efa8ecb435"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.landingfolio.com/">landingfolio</a>，landing页模版大全，寻找设计灵感必看</li></ul><ul class="notion-list notion-list-disc notion-block-6cca8960c3234e4ca3f0fc2db025525c"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.tailwindawesome.com/">tailwindawesome</a>，模版大全，跟上面一个类似</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-1a624c3d038f4ae096be14c7bf1c2d3f" data-id="1a624c3d038f4ae096be14c7bf1c2d3f"><span><div id="1a624c3d038f4ae096be14c7bf1c2d3f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1a624c3d038f4ae096be14c7bf1c2d3f" title="icon库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">icon库</span></span></h3><ul class="notion-list notion-list-disc notion-block-723959a51e1742b19c64c55406fc8630"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://heroicons.com/">heroicons</a>，官方推荐的svg库</li></ul><div class="notion-blank notion-block-45fef850341542df8d5ff9145245619a"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-9a6fe0b5029a4d9ea21de6ce33935da6" data-id="9a6fe0b5029a4d9ea21de6ce33935da6"><span><div id="9a6fe0b5029a4d9ea21de6ce33935da6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9a6fe0b5029a4d9ea21de6ce33935da6" title="表单相关"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">表单相关</span></span></h3><ul class="notion-list notion-list-disc notion-block-289510a9349d410299cecac132252565"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react-hook-form.com/">react-hook-form</a>，高质量表单控制校验库，以性能好著称</li></ul><div class="notion-blank notion-block-196884fe0c92406aaef1383da94dce73"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-7420578e403649c9b1637c604174250f" data-id="7420578e403649c9b1637c604174250f"><span><div id="7420578e403649c9b1637c604174250f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7420578e403649c9b1637c604174250f" title="React Hooks库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">React Hooks库</span></span></h3><ul class="notion-list notion-list-disc notion-block-9457a51a094f4a0ba00eed46a6657ef1"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ahooks.js.org/zh-CN/guide">ahooks</a>，阿里出的Hooks库，api比较全</li></ul><ul class="notion-list notion-list-disc notion-block-f64292a8c791433f8c7afd3b516100a1"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://antonioru.github.io/beautiful-react-hooks/"><code class="notion-inline-code">beautiful-react-hooks</code></a>，api数量没那么多，但质量还可以</li></ul><ul class="notion-list notion-list-disc notion-block-9771f3838b9b46d586e6fdd7f0e857c7"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/streamich/react-use">react-use</a>，api较丰富，跟ahooks有不少重合的</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-e87f2d7003814f2a98dd7df21ed71cc3" data-id="e87f2d7003814f2a98dd7df21ed71cc3"><span><div id="e87f2d7003814f2a98dd7df21ed71cc3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e87f2d7003814f2a98dd7df21ed71cc3" title="图表库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">图表库</span></span></h3><ul class="notion-list notion-list-disc notion-block-ea34d2a0f4be444b878bff5d9fbe8080"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/recharts/recharts">recharts</a>,使用 React 和 D3 构建的重新定义的图表库，界面比较简洁，demo比较丰富，API设计有点Bizchart的影子</li></ul><div class="notion-blank notion-block-9dcde1d7fcfc42e789f903f9ad203224"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d08f609d7e8447639bf215c0b4e035c4" data-id="d08f609d7e8447639bf215c0b4e035c4"><span><div id="d08f609d7e8447639bf215c0b4e035c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d08f609d7e8447639bf215c0b4e035c4" title="动画库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">动画库</span></span></h3><ul class="notion-list notion-list-disc notion-block-8419c71464c64a32a59a719e49340659"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/pmndrs/react-spring">react-spring</a>,基于弹簧物理学的现代动画库，自定义程度比较高，且和nextjs配合的比较好(即将支持SSR)</li></ul><ul class="notion-list notion-list-disc notion-block-033e54c7e2b94e8b81b328dbbca5422b"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.framer.com/motion/">Framer Motion</a>，</li></ul><ul class="notion-list notion-list-disc notion-block-2e8b1781ba584be0bcd23a3c0307e974"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://reactcommunity.org/react-transition-group/">reat-transititon-group</a><span style="padding:0.5em"></span></li></ul><ul class="notion-list notion-list-disc notion-block-6964b5f9ce5544b3b41ee62957c2bf38"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/chenglou/react-motion">react-motion</a><span style="padding:0.5em"></span></li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-26f159456650441e843e775d80c6cc0d" data-id="26f159456650441e843e775d80c6cc0d"><span><div id="26f159456650441e843e775d80c6cc0d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#26f159456650441e843e775d80c6cc0d" title="其他"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">其他</span></span></h3><ul class="notion-list notion-list-disc notion-block-1a0725e823894eb7a7a7800d251956ac"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/lukeed/clsx">clsx</a>，动态组合className神器，用过都说好</li></ul><ul class="notion-list notion-list-disc notion-block-e53dca49421c4bc28fb6e68aa84170f9"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/dcastil/tailwind-merge">tailwind-merge</a>，合并tailwind且能避免样式冲突</li></ul><ul class="notion-list notion-list-disc notion-block-592e7de080c44163818f02342139509c"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://swr.vercel.app/zh-CN">swr</a>，官方请求数据的react hooks库，绝无仅有的数据缓存能力,搭配nextjs必备</li></ul><ul class="notion-list notion-list-disc notion-block-cd7e761ac43e4ad789f04c3231223deb"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/iamvishnusankar/next-sitemap">next-sitemap</a>，自动生成sitemap，在nextjs中做seo很好用</li></ul><ul class="notion-list notion-list-disc notion-block-943c149ad98a4495b5c5829aa34578f6"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/garmeeh/next-seo">next-seo</a>，可以让您在 Next.js 项目中更轻松地管理 SEO</li></ul><ul class="notion-list notion-list-disc notion-block-5dfffc01a9d54ec68449bec908ae6caa"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/pacocoursey/next-themes">next-themes</a>，2行代码完美的Next.js深色模式。支持系统偏好设置和任何其他主题</li></ul><ul class="notion-list notion-list-disc notion-block-dfb630c62ade4eea91ec2afdf1db7bfe"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/timolins/react-hot-toast">react-hot-toast</a>，轻量级小于<em>5kb</em>的弹窗消息组件</li></ul><div class="notion-blank notion-block-5793a7a1786b4290b7401db8924a1476"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[一文读懂Promise]]></title>
            <link>https://notionext-three.vercel.app/article/promise</link>
            <guid>https://notionext-three.vercel.app/article/promise</guid>
            <pubDate>Sun, 24 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Promise原理解析]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-bb5a3cf91d1c47ed94dafaa802faf85b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-1437dfff304847e2bf4b27dabc6f265e" data-id="1437dfff304847e2bf4b27dabc6f265e"><span><div id="1437dfff304847e2bf4b27dabc6f265e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1437dfff304847e2bf4b27dabc6f265e" title="全文目录"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">全文目录</span></span></h2><div class="notion-text notion-block-ce2af3bc2a0446c68cd2bb15e58c4373">可以学到以下内容：</div><ul class="notion-list notion-list-disc notion-block-53c675c169b74d8b9869433a179722ac"><li>Promise的几道基础题</li></ul><ul class="notion-list notion-list-disc notion-block-a8ddc39dca7d403bb792b8dd69cabf0a"><li>Promise结合setTimeout</li></ul><ul class="notion-list notion-list-disc notion-block-330e7cd9d6b54c4b80e9a54874ff4847"><li>Promise中的then、catch、finally</li></ul><ul class="notion-list notion-list-disc notion-block-ca6611b94f4b4202bbc5bbfd1c73558f"><li> Promise中的all和race</li></ul><ul class="notion-list notion-list-disc notion-block-a8b0ab7139c44e99b0d141ea0abdda3c"><li> async/await的几道题</li></ul><ul class="notion-list notion-list-disc notion-block-a730cb57da79418183c8b8874c37f7de"><li> async处理错误</li></ul><ul class="notion-list notion-list-disc notion-block-48d26f9bf22346868d61c1be12ee437f"><li>综合题</li></ul><ul class="notion-list notion-list-disc notion-block-e8926a4dbfd640cabbb185457e2d80d4"><li>几道大厂的面试题</li></ul><div class="notion-blank notion-block-c928bde2bcbb4244a1ccda4f9d1db6cb"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-2ac3978b951d4eedb07128adf0f4a09e" data-id="2ac3978b951d4eedb07128adf0f4a09e"><span><div id="2ac3978b951d4eedb07128adf0f4a09e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2ac3978b951d4eedb07128adf0f4a09e" title="前期准备"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">前期准备</span></span></h3><div class="notion-text notion-block-91a8e5f519c04f7b9de99a1a02460d2f"><code class="notion-inline-code"><b>event loop</b></code><b>它的执行顺序：</b></div><ul class="notion-list notion-list-disc notion-block-1a0b4153e5bc4d119d10a041136e3f88"><li>一开始整个脚本作为一个宏任务执行</li></ul><ul class="notion-list notion-list-disc notion-block-2f4bfc3bc8ab446db2f50af232fe47a0"><li>执行过程中同步代码直接执行，宏任务进入宏任务队列，微任务进入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-4f6cecaaf8804cc9bf26d9a334683868"><li>当前宏任务执行完出队，检查微任务列表，有则依次执行，直到全部执行完</li></ul><ul class="notion-list notion-list-disc notion-block-564419ad41fb4b748010f38ff7cfcfd2"><li>执行浏览器UI线程的渲染工作</li></ul><ul class="notion-list notion-list-disc notion-block-1004d7e1e69542eaaea58652567b9055"><li>检查是否有<code class="notion-inline-code">Web Worker</code>任务，有则执行</li></ul><ul class="notion-list notion-list-disc notion-block-fd2bc711668f409e8a5da6f90b67fb80"><li>执行完本轮的宏任务，回到2，依此循环，直到宏任务和微任务队列都为空</li></ul><div class="notion-text notion-block-ab4a5234649f4efca5b2c522238d3f3d"><b>微任务包括：</b><code class="notion-inline-code">MutationObserver</code>、<code class="notion-inline-code">Promise.then()或catch()</code>、<code class="notion-inline-code">Promise为基础开发的其它技术，比如fetch API</code>、<code class="notion-inline-code">V8</code>的垃圾回收过程、<code class="notion-inline-code">Node独有的process.nextTick</code>。</div><div class="notion-text notion-block-5bf0df840acc4d9ba299db138e1cb034"><b>宏任务包括</b>：<code class="notion-inline-code">script</code> 、<code class="notion-inline-code">setTimeout</code>、<code class="notion-inline-code">setInterval</code> 、<code class="notion-inline-code">setImmediate</code> 、<code class="notion-inline-code">I/O</code> 、<code class="notion-inline-code">UI rendering</code>。</div><div class="notion-callout notion-gray_background_co notion-block-844f600db5e241f4a2d07cd83e2d2e6a"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><b>注意</b>⚠️：在所有任务开始的时候，由于宏任务中包括了<code class="notion-inline-code">script</code>，所以浏览器会先执行一个宏任务，在这个过程中你看到的延迟任务(例如<code class="notion-inline-code">setTimeout</code>)将被放到下一轮宏任务中来执行。</div></div><div class="notion-blank notion-block-745c6525fd9d491da78ccedc19012509"> </div><div class="notion-blank notion-block-083f807b1bd2439ea25fb0f844c6112b"> </div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-43ec9beecfcc4d07a02a069497626c1b" data-id="43ec9beecfcc4d07a02a069497626c1b"><span><div id="43ec9beecfcc4d07a02a069497626c1b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#43ec9beecfcc4d07a02a069497626c1b" title="1. Promise的几道基础题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>1. Promise的几道基础题</b></span></span></h4><div class="notion-text notion-block-a5785ac9529f4b5b84317c073970ca38"><b>1.1 题目一</b></div><div class="notion-text notion-block-b2e6cfb7d5b744f18e0ae3959ba2a065">过程分析：</div><ul class="notion-list notion-list-disc notion-block-c594555981624c2a9a83e45af7bb0bd5"><li>从上至下，先遇到<code class="notion-inline-code">new Promise</code>，执行该构造函数中的代码<code class="notion-inline-code">promise1</code></li></ul><ul class="notion-list notion-list-disc notion-block-c5423c9fc4744f83834bc8f1b75c7d52"><li>然后执行同步代码<code class="notion-inline-code">1</code>，此时<code class="notion-inline-code">promise1</code>没有被<code class="notion-inline-code">resolve</code>或者<code class="notion-inline-code">reject</code>，因此状态还是<code class="notion-inline-code">pending</code></li></ul><div class="notion-text notion-block-4eaf735da85f4746a645be8c67d666a4">结果：</div><div class="notion-text notion-block-b43867e7d929455cb93a54c9b123d403"><b>1.2 题目二</b></div><div class="notion-text notion-block-d32cfe5c390a447bbc6efc55c637f4df">过程分析：</div><ul class="notion-list notion-list-disc notion-block-3e66c6ebefbe496ca4dbbef640a6b491"><li>从上至下，先遇到<code class="notion-inline-code">new Promise</code>，执行其中的同步代码<code class="notion-inline-code">1</code></li></ul><ul class="notion-list notion-list-disc notion-block-516da42cb92640e29eda8dbbc968ce2b"><li>再遇到<code class="notion-inline-code">resolve(&#x27;success&#x27;)</code>， 将<code class="notion-inline-code">promise</code>的状态改为了<code class="notion-inline-code">resolved</code>并且将值保存下来</li></ul><ul class="notion-list notion-list-disc notion-block-258efa9967e1442694585ebfe2dddc6e"><li>继续执行同步代码<code class="notion-inline-code">2</code></li></ul><ul class="notion-list notion-list-disc notion-block-05b8d6e7dc014c81b512f0be41718df5"><li>跳出<code class="notion-inline-code">promise</code>，往下执行，碰到<code class="notion-inline-code">promise.then</code>这个微任务，将其加入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-de6a2d61a2af4ab3ace04b43237bfda2"><li>执行同步代码<code class="notion-inline-code">4</code></li></ul><ul class="notion-list notion-list-disc notion-block-d7222a82ac6440aead54aaa6238b7064"><li>本轮宏任务全部执行完毕，检查微任务队列，发现<code class="notion-inline-code">promise.then</code>这个微任务且状态为<code class="notion-inline-code">resolved</code>，执行它。</li></ul><div class="notion-text notion-block-f1dd36d29d93467bad584a13886f3e30">结果：</div><div class="notion-text notion-block-ee9273c46f0b44aa941969d2a4e036c6"><b>1.3 题目三</b></div><div class="notion-text notion-block-5585664248994866a9f153a5e2bc10f9">过程分析</div><ul class="notion-list notion-list-disc notion-block-bf880ff13b6e4fcd893098ddc6fd4fe8"><li>和题目二相似，只不过在<code class="notion-inline-code">promise</code>中并没有<code class="notion-inline-code">resolve</code>或者<code class="notion-inline-code">reject</code></li></ul><ul class="notion-list notion-list-disc notion-block-b5671d7c8b1d4f24bc06bb959285444b"><li>因此<code class="notion-inline-code">promise.then</code>并不会执行，它只有在被改变了状态之后才会执行。</li></ul><div class="notion-text notion-block-8313d51203f944a1950f68aa1d8ae373">结果：</div><div class="notion-text notion-block-fc13a3e7f8e74f5e994a486ed03a2474"><b>1.4 题目四</b></div><div class="notion-text notion-block-4f782d3c2ccd40ff837fb5e6da3d340d">过程分析：</div><ul class="notion-list notion-list-disc notion-block-25919831aa9b41be9c148af980729b60"><li>从上至下，先遇到<code class="notion-inline-code">new Promise</code>，执行该构造函数中的代码<code class="notion-inline-code">promise1</code></li></ul><ul class="notion-list notion-list-disc notion-block-d43e6f1fea7941cc9897731c49993bfa"><li>碰到<code class="notion-inline-code">resolve</code>函数, 将<code class="notion-inline-code">promise1</code>的状态改变为<code class="notion-inline-code">resolved</code>, 并将结果保存下来</li></ul><ul class="notion-list notion-list-disc notion-block-5f5c6c58b51348578df7cacfec6494c3"><li>碰到<code class="notion-inline-code">promise1.then</code>这个微任务，将它放入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-fca33fc0139a4dc4ad52825b5b99aa3e"><li><code class="notion-inline-code">promise2</code>是一个新的状态为<code class="notion-inline-code">pending</code>的<code class="notion-inline-code">Promise</code></li></ul><ul class="notion-list notion-list-disc notion-block-a2a04e066f06473993319f69718c1a5c"><li>执行同步代码<code class="notion-inline-code">1</code>， 同时打印出<code class="notion-inline-code">promise1</code>的状态是<code class="notion-inline-code">resolved</code></li></ul><ul class="notion-list notion-list-disc notion-block-a3e19a14296549dfa8b976c318016be6"><li>执行同步代码<code class="notion-inline-code">2</code>，同时打印出<code class="notion-inline-code">promise2</code>的状态是<code class="notion-inline-code">pending</code></li></ul><ul class="notion-list notion-list-disc notion-block-5d605a25d2494079aae83551024a880d"><li>宏任务执行完毕，查找微任务队列，发现<code class="notion-inline-code">promise1.then</code>这个微任务且状态为<code class="notion-inline-code">resolved</code>，执行它。</li></ul><div class="notion-text notion-block-fef640d8e5474c2eb8cb5cd8e64e9245">结果：</div><div class="notion-text notion-block-73afee6fda54444785232b8e1999149d"><b>1.5 题目五</b></div><div class="notion-text notion-block-225daf9b285842f3a7551920393ccdfd">这道题里最先执行的是<code class="notion-inline-code">&#x27;start&#x27;</code>吗 🤔️ ？</div><div class="notion-text notion-block-7856d393229e4a5e86af3ed944610105">请仔细看看哦，<code class="notion-inline-code">fn</code>函数它是直接返回了一个<code class="notion-inline-code">new Promise</code>的，而且<code class="notion-inline-code">fn</code>函数的调用是在<code class="notion-inline-code">start</code>之前，所以它里面的内容应该会先执行。</div><div class="notion-text notion-block-cfe9ee4edd584fcebdcabaf8d3e971c1">结果</div><div class="notion-text notion-block-1a7fbda00d454c5d8cb435cddfff7574"><b>1.6 题目六</b></div><div class="notion-text notion-block-6627f6666e074e35aecd01550d00b868">如果把<code class="notion-inline-code">fn</code>的调用放到<code class="notion-inline-code">start</code>之后呢？</div><div class="notion-text notion-block-c77a56f4d1a0454eb9d5ef12946633d0">是的，现在<code class="notion-inline-code">start</code>就在<code class="notion-inline-code">1</code>之前打印出来了，因为<code class="notion-inline-code">fn</code>函数是之后执行的。</div><div class="notion-text notion-block-3d93674a103f49fc84718f1b50f10546"><b>注意⚠️</b>：之前我们很容易就以为看到new Promise()就执行它的第一个参数函数了，其实这是不对的，就像这两道题中，我们得注意它是不是被包裹在函数当中，如果是的话，只有在函数调用的时候才会执行。</div><div class="notion-text notion-block-a887d16d014e408da6995639d640f01a">答案：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-84b6a0fe24d8407ba5ce10e3700df381" data-id="84b6a0fe24d8407ba5ce10e3700df381"><span><div id="84b6a0fe24d8407ba5ce10e3700df381" class="notion-header-anchor"></div><a class="notion-hash-link" href="#84b6a0fe24d8407ba5ce10e3700df381" title="2. Promise结合setTimeout"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2. Promise结合setTimeout</b></span></span></h4><div class="notion-text notion-block-3f9368c3b819459cacb5d0ac89a7de16"><b>2.1 题目一</b></div><div class="notion-text notion-block-b7bd647e6cbf429eae11999e7542683d">过程分析：</div><ul class="notion-list notion-list-disc notion-block-83bd272f59b34e4888dcb41c6383ae37"><li>刚开始整个脚本作为一个宏任务来执行，对于同步代码直接压入执行栈进行执行，因此先打印出<code class="notion-inline-code">start</code>和<code class="notion-inline-code">end</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-070ae3bd2eb04144bdfce15c2578c9bb"><li><code class="notion-inline-code">setTimout</code>作为一个宏任务被放入宏任务队列(下一个)</li></ul><ul class="notion-list notion-list-disc notion-block-08ef9f8db6ac49d0b20b89b05e89ebf5"><li><code class="notion-inline-code">Promise.then</code>作为一个微任务被放入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-1e035bfafbff47eeaf3aa322d95647c6"><li>本次宏任务执行完，检查微任务，发现<code class="notion-inline-code">Promise.then</code>，执行它</li></ul><ul class="notion-list notion-list-disc notion-block-4d1fa4ebb06d48559b29bae17b625008"><li>接下来进入下一个宏任务，发现<code class="notion-inline-code">setTimeout</code>，执行。</li></ul><div class="notion-text notion-block-35e426ace1c34d1aa494270f39de90d1">结果：</div><div class="notion-text notion-block-181a64245b2f4427ac0eef7260f83043"><b>2.2 题目二</b></div><div class="notion-text notion-block-45cd6f3a5fa64c13b269df7711776c0b">过程分析：</div><div class="notion-text notion-block-48ae3583cd2a4cc6b98aa7748b562915">和题目<code class="notion-inline-code">1.2</code>很像，不过在<code class="notion-inline-code">resolve</code>的外层加了一层<code class="notion-inline-code">setTimeout</code>定时器。</div><ul class="notion-list notion-list-disc notion-block-597f835fdeef45698bafaa2997a938b7"><li>从上至下，先遇到<code class="notion-inline-code">new Promise</code>，执行该构造函数中的代码<code class="notion-inline-code">1</code></li></ul><ul class="notion-list notion-list-disc notion-block-0812525df37f40eaa4dbe91dfbd0b71a"><li>然后碰到了定时器，将这个定时器中的函数放到下一个宏任务的延迟队列中等待执行</li></ul><ul class="notion-list notion-list-disc notion-block-455599da026a42178657905bff069110"><li>执行同步代码<code class="notion-inline-code">2</code></li></ul><ul class="notion-list notion-list-disc notion-block-f4477ce1383b47c393f89c5eda8378ab"><li>跳出<code class="notion-inline-code">promise</code>函数，遇到<code class="notion-inline-code">promise.then</code>，但其状态还是为<code class="notion-inline-code">pending</code>，这里理解为先不执行</li></ul><ul class="notion-list notion-list-disc notion-block-30cd6cfeca7743ed8aaf8f88772a2b03"><li>执行同步代码<code class="notion-inline-code">4</code></li></ul><ul class="notion-list notion-list-disc notion-block-3c7a31e369a94bf8bd29c91785170350"><li>一轮循环过后，进入第二次宏任务，发现延迟队列中有<code class="notion-inline-code">setTimeout</code>定时器，执行它</li></ul><ul class="notion-list notion-list-disc notion-block-c72903331c954b5ab3d2286e735d3a98"><li>首先执行<code class="notion-inline-code">timerStart</code>，然后遇到了<code class="notion-inline-code">resolve</code>，将<code class="notion-inline-code">promise</code>的状态改为<code class="notion-inline-code">resolved</code>且保存结果并将之前的<code class="notion-inline-code">promise.then</code>推入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-31958a5f231542cf9028e8f09d7505df"><li>继续执行同步代码<code class="notion-inline-code">timerEnd</code></li></ul><ul class="notion-list notion-list-disc notion-block-8e50ce6e69984453845c53389e93c5d8"><li>宏任务全部执行完毕，查找微任务队列，发现<code class="notion-inline-code">promise.then</code>这个微任务，执行它。</li></ul><div class="notion-text notion-block-13fadbdb12774fffa1d7ea2ccb6d034c">因此执行结果为：</div><div class="notion-text notion-block-b47bdf1a3e6c495cab5d35d920e579a2"><b>2.3 题目三</b></div><div class="notion-text notion-block-a4721f26dbf44bb2a11fcda76d1a8362">题目三分了两个题目，因为看着都差不多，不过执行的结果却不一样，大家不妨先猜猜下面两个题目分别执行什么：</div><div class="notion-text notion-block-75be4ee8d26b4d819679c3ee2f7e9309"><b>(1)</b>:</div><div class="notion-text notion-block-4dad402bfd644a9497eb5d3d0560a83d"><b>(2)</b>:</div><div class="notion-text notion-block-6f80f0d3b2c94052b4c2decc1b3e387b"><b>执行结果：</b></div><div class="notion-text notion-block-45b789829c4a4f13b290138cdd2bfb38">这两个例子，看着好像只是把第一个定时器中的内容换了一下而已。</div><div class="notion-text notion-block-76c9f95b1f63488191b5965e4e7e6d42">一个是为定时器<code class="notion-inline-code">timer3</code>，一个是为<code class="notion-inline-code">Promise.then</code></div><div class="notion-text notion-block-cf8b50ffeed1476f8789b183439bbd94">但是如果是定时器<code class="notion-inline-code">timer3</code>的话，它会在<code class="notion-inline-code">timer2</code>后执行，而<code class="notion-inline-code">Promise.then</code>却是在<code class="notion-inline-code">timer2</code>之前执行。</div><div class="notion-text notion-block-899ce74b2f984e95b88a652b52b4dbf6">你可以这样理解，<code class="notion-inline-code">Promise.then</code>是微任务，它会被加入到本轮中的微任务列表，而定时器<code class="notion-inline-code">timer3</code>是宏任务，它会被加入到下一轮的宏任务中。</div><div class="notion-text notion-block-665e961c69fb4d07befa4894ce3fbd99">理解完这两个案例，可以来看看下面一道比较难的题目了。</div><div class="notion-text notion-block-8520c2ecdf0146ac97b97f51df0e3008"><b>2.3 题目三</b></div><div class="notion-text notion-block-bf2f1bb29a67437b8a02cb5c23a33a87">这道题稍微的难一些，在<code class="notion-inline-code">promise</code>中执行定时器，又在定时器中执行<code class="notion-inline-code">promise</code>；</div><div class="notion-text notion-block-30d9a6a5997a4d1a8bd20f689635cdbd">并且要注意的是，这里的<code class="notion-inline-code">Promise</code>是直接<code class="notion-inline-code">resolve</code>的，而之前的<code class="notion-inline-code">new Promise</code>不一样。</div><div class="notion-text notion-block-f6fd7974fac143d6a3cca394c4121549">(偷偷告诉你，这道题往下一点有流程图)</div><div class="notion-text notion-block-16f619b1bbaa4304b147a0a097fbd368">因此过程分析为：</div><ul class="notion-list notion-list-disc notion-block-6d48abffa267498081379e16d2cafc59"><li>刚开始整个脚本作为第一次宏任务来执行，我们将它标记为<b>宏1</b>，从上至下执行</li></ul><ul class="notion-list notion-list-disc notion-block-d249ef97d57a448dbb748e8ab858d38f"><li>遇到<code class="notion-inline-code">Promise.resolve().then</code>这个微任务，将<code class="notion-inline-code">then</code>中的内容加入第一次的微任务队列标记为<b>微1</b></li></ul><ul class="notion-list notion-list-disc notion-block-5ff76df00fab4eeaa2345cd718ffaf48"><li>遇到定时器<code class="notion-inline-code">timer1</code>，将它加入下一次宏任务的延迟列表，标记为<b>宏2</b>，等待执行(先不管里面是什么内容)</li></ul><ul class="notion-list notion-list-disc notion-block-41ec22090ae342e6bdf3b465c93dd3f3"><li>执行<b>宏1</b>中的同步代码<code class="notion-inline-code">start</code></li></ul><ul class="notion-list notion-list-disc notion-block-5ad9ffe28baf4f518cc5fda9cb7fdf64"><li>第一次宏任务(<b>宏1</b>)执行完毕，检查第一次的微任务队列(<b>微1</b>)，发现有一个<code class="notion-inline-code">promise.then</code>这个微任务需要执行</li></ul><ul class="notion-list notion-list-disc notion-block-68487b492e42415495b81043c28e12f1"><li>执行打印出<b>微1</b>中同步代码<code class="notion-inline-code">promise1</code>，然后发现定时器<code class="notion-inline-code">timer2</code>，将它加入<b>宏2</b>的后面，标记为<b>宏3</b></li></ul><ul class="notion-list notion-list-disc notion-block-31f4fa70fb0d41688fb9da04a23bc392"><li>第一次微任务队列(<b>微1</b>)执行完毕，执行第二次宏任务(<b>宏2</b>)，首先执行同步代码<code class="notion-inline-code">timer1</code></li></ul><ul class="notion-list notion-list-disc notion-block-ab2ea63c0dbe4abd8875126c9feda622"><li>然后遇到了<code class="notion-inline-code">promise2</code>这个微任务，将它加入此次循环的微任务队列，标记为<b>微2</b></li></ul><ul class="notion-list notion-list-disc notion-block-716793482cb84d08b88f994140373df9"><li><b>宏2</b>中没有同步代码可执行了，查找本次循环的微任务队列(<b>微2</b>)，发现了<code class="notion-inline-code">promise2</code>，执行它</li></ul><ul class="notion-list notion-list-disc notion-block-90cdc9ab83d84ed1b740f19477badf93"><li>第二轮执行完毕，执行<b>宏3</b>，打印出<code class="notion-inline-code">timer2</code></li></ul><div class="notion-text notion-block-ec070e82290b4e018273058da47abcc3">所以结果为：</div><div class="notion-text notion-block-6f927119b6ec43f39f11bbfca79151ad">如果感觉有点绕的话，可以看下面这张图，就一目了然了。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8b6447eb813e4a39b8d396d24424955f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F2f0241cb-4f07-4d35-8252-c478d8b88123%2F40d2182b-129f-434f-86e6-b32929feb88f%2FWechatIMG30.jpg?table=block&amp;id=8b6447eb-813e-4a39-b8d3-96d24424955f" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a0cd99f82e2c4244a9873621222e70c9"><b>2.4 题目四</b></div><div class="notion-text notion-block-c058adce07894dc78af625fdb02536b6">过程分析：</div><ul class="notion-list notion-list-disc notion-block-bdc2d9c9fc21435ab3c6c49f4f6e93fb"><li>从上至下，先执行第一个<code class="notion-inline-code">new Promise</code>中的函数，碰到<code class="notion-inline-code">setTimeout</code>将它加入下一个宏任务列表</li></ul><ul class="notion-list notion-list-disc notion-block-5174b803a82c494fa7c5b339893d6012"><li>跳出<code class="notion-inline-code">new Promise</code>，碰到<code class="notion-inline-code">promise1.then</code>这个微任务，但其状态还是为<code class="notion-inline-code">pending</code>，这里理解为先不执行</li></ul><ul class="notion-list notion-list-disc notion-block-f0e33fd1c0b043b8bfad7b220a33a5b8"><li><code class="notion-inline-code">promise2</code>是一个新的状态为<code class="notion-inline-code">pending</code>的<code class="notion-inline-code">Promise</code></li></ul><ul class="notion-list notion-list-disc notion-block-4136d02a850f436eae5fce1bcaadafe6"><li>执行同步代码<code class="notion-inline-code">console.log(&#x27;promise1&#x27;)</code>，且打印出的<code class="notion-inline-code">promise1</code>的状态为<code class="notion-inline-code">pending</code></li></ul><ul class="notion-list notion-list-disc notion-block-ef6abebb12104e75bbb4876414f599ba"><li>执行同步代码<code class="notion-inline-code">console.log(&#x27;promise2&#x27;)</code>，且打印出的<code class="notion-inline-code">promise2</code>的状态为<code class="notion-inline-code">pending</code></li></ul><ul class="notion-list notion-list-disc notion-block-78868056cae84e019cab3809a2ae0a84"><li>碰到第二个定时器，将其放入下一个宏任务列表</li></ul><ul class="notion-list notion-list-disc notion-block-d4e635fb308a46d8988fa6394a04272e"><li>第一轮宏任务执行结束，并且没有微任务需要执行，因此执行第二轮宏任务</li></ul><ul class="notion-list notion-list-disc notion-block-e777d4fa70314dad81df7110ee38d26f"><li>先执行第一个定时器里的内容，将<code class="notion-inline-code">promise1</code>的状态改为<code class="notion-inline-code">resolved</code>且保存结果并将之前的<code class="notion-inline-code">promise1.then</code>推入微任务队列</li></ul><ul class="notion-list notion-list-disc notion-block-7c46df628b3045a1938ff3f64c40db36"><li>该定时器中没有其它的同步代码可执行，因此执行本轮的微任务队列，也就是<code class="notion-inline-code">promise1.then</code>，它抛出了一个错误，且将<code class="notion-inline-code">promise2</code>的状态设置为了<code class="notion-inline-code">rejected</code></li></ul><ul class="notion-list notion-list-disc notion-block-26c952c4c9b74561b8c55a26954461aa"><li>第一个定时器执行完毕，开始执行第二个定时器中的内容</li></ul><ul class="notion-list notion-list-disc notion-block-cd96155c8b694a1a87d0a93cdfe2eba9"><li>打印出<code class="notion-inline-code">&#x27;promise1&#x27;</code>，且此时<code class="notion-inline-code">promise1</code>的状态为<code class="notion-inline-code">resolved</code></li></ul><ul class="notion-list notion-list-disc notion-block-6444e870d82a41af8ae802026fcced02"><li>打印出<code class="notion-inline-code">&#x27;promise2&#x27;</code>，且此时<code class="notion-inline-code">promise2</code>的状态为<code class="notion-inline-code">rejected</code></li></ul><div class="notion-text notion-block-e600bbb65238481ea440aa8048f022b8">完整的结果为：</div><div class="notion-text notion-block-9766b3b469a342fcad7c173c89a38f0d"><b>2.5 题目五</b></div><div class="notion-text notion-block-ef12c23370934ea7a1c8c8b9484b233c">结果：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-efc968543e9d4f1abffa1081c4ce31aa" data-id="efc968543e9d4f1abffa1081c4ce31aa"><span><div id="efc968543e9d4f1abffa1081c4ce31aa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#efc968543e9d4f1abffa1081c4ce31aa" title="3. Promise中的then、catch、finally"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3. Promise中的then、catch、finally</b></span></span></h4><div class="notion-text notion-block-ca9649d675b2431aa8e34ce6ff5b226a"><b>总结：</b></div><ol start="1" class="notion-list notion-list-numbered notion-block-b7a42282bc6743e5afd84724f90bb5e0"><li><code class="notion-inline-code">Promise</code>的状态一经改变就不能再改变。(见3.1)</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3aa17505bd3c4168929cc39f44056c05"><li><code class="notion-inline-code">.then</code>和<code class="notion-inline-code">.catch</code>都会返回一个新的<code class="notion-inline-code">Promise</code>。(上面的👆1.4证明了)</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-aa09001731e94a5484209a3a23b6fbff"><li><code class="notion-inline-code">catch</code>不管被连接到哪里，都能捕获上层未捕捉过的错误。(见3.2)</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-c0ca7fea25324f469838cdc0480e20ca"><li>在<code class="notion-inline-code">Promise</code>中，返回任意一个非 <code class="notion-inline-code">promise</code> 的值都会被包裹成 <code class="notion-inline-code">promise</code> 对象，例如<code class="notion-inline-code">return 2</code>会被包装为<code class="notion-inline-code">return Promise.resolve(2)</code>。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-195ba322265a4f7c835fc58727dfd9a5"><li><code class="notion-inline-code">Promise</code> 的 <code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 可以被调用多次, 但如果<code class="notion-inline-code">Promise</code>内部的状态一经改变，并且有了一个值，那么后续每次调用<code class="notion-inline-code">.then</code>或者<code class="notion-inline-code">.catch</code>的时候都会直接拿到该值。(见3.5)</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-d2dae7b018f546d8b030d4258b3970f5"><li><code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 中 <code class="notion-inline-code">return</code> 一个 <code class="notion-inline-code">error</code> 对象并不会抛出错误，所以不会被后续的 <code class="notion-inline-code">.catch</code> 捕获。(见3.6)</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-b9832f63543d47ff8cc4f3ac44d615c0"><li><code class="notion-inline-code">.then</code> 或 <code class="notion-inline-code">.catch</code> 返回的值不能是 promise 本身，否则会造成死循环。(见3.7)</li></ol><ol start="8" class="notion-list notion-list-numbered notion-block-e5f441fe307948a0894c38e00809914e"><li><code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 的参数期望是函数，传入非函数则会发生值透传。(见3.8)</li></ol><ol start="9" class="notion-list notion-list-numbered notion-block-4b3d3d11d3564861a46fd0de06d9b094"><li><code class="notion-inline-code">.then</code>方法是能接收两个参数的，第一个是处理成功的函数，第二个是处理失败的函数，再某些时候你可以认为<code class="notion-inline-code">catch</code>是<code class="notion-inline-code">.then</code>第二个参数的简便写法。(见3.9)</li></ol><ol start="10" class="notion-list notion-list-numbered notion-block-24444c540c75402cbc13a66f2fae34e8"><li><code class="notion-inline-code">.finally</code>方法也是返回一个<code class="notion-inline-code">Promise</code>，他在<code class="notion-inline-code">Promise</code>结束的时候，无论结果为<code class="notion-inline-code">resolved</code>还是<code class="notion-inline-code">rejected</code>，都会执行里面的回调函数。</li></ol><div class="notion-text notion-block-734a39d2b74842079f882205ad2da92a"><b>3.1 题目一</b></div><div class="notion-text notion-block-63136f881d9f487880d69c1a5fdc6cfc">构造函数中的 <code class="notion-inline-code">resolve</code> 或 <code class="notion-inline-code">reject</code> 只有第一次执行有效，多次调用没有任何作用 。验证了第一个结论，<code class="notion-inline-code">Promise</code>的状态一经改变就不能再改变。</div><div class="notion-text notion-block-f2aaa744076248d3b31b00351634a87c"><b>3.2 题目二</b></div><div class="notion-text notion-block-5ae428ce25cb4cf9ae2ec74d1600efc3">结果：</div><div class="notion-text notion-block-087e3886a02540959c4042d0c234acb1">验证了第三个结论，<code class="notion-inline-code">catch</code>不管被连接到哪里，都能捕获上层未捕捉过的错误。</div><div class="notion-text notion-block-e06030856df2402e82f36e33562a8220">至于<code class="notion-inline-code">then3</code>也会被执行，那是因为<code class="notion-inline-code">catch()</code>也会返回一个<code class="notion-inline-code">Promise</code>，且由于这个<code class="notion-inline-code">Promise</code>没有返回值，所以打印出来的是<code class="notion-inline-code">undefined</code>。</div><div class="notion-text notion-block-1162cae00c8049d4b72fe254d130851f"><b>3.3 题目三</b></div><div class="notion-text notion-block-db7d4a8cd90f45768f39165543965514">结果：</div><div class="notion-text notion-block-744f8914db024c4c8e47cc11115fc108"><code class="notion-inline-code">Promise</code>可以链式调用，不过<code class="notion-inline-code">promise</code> 每次调用 <code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 都会返回一个新的 <code class="notion-inline-code">promise</code>，从而实现了链式调用, 它并不像一般我们任务的链式调用一样<code class="notion-inline-code">return this</code>。</div><div class="notion-text notion-block-af359ac02d6a4528b44bd13e87611a3f">上面的输出结果之所以依次打印出<code class="notion-inline-code">1</code>和<code class="notion-inline-code">2</code>，那是因为<code class="notion-inline-code">resolve(1)</code>之后走的是第一个<code class="notion-inline-code">then</code>方法，并没有走<code class="notion-inline-code">catch</code>里，所以第二个<code class="notion-inline-code">then</code>中的<code class="notion-inline-code">res</code>得到的实际上是第一个<code class="notion-inline-code">then</code>的返回值。</div><div class="notion-text notion-block-5da39aefea7a46c1af529e3d1952c1ea">且<code class="notion-inline-code">return 2</code>会被包装成<code class="notion-inline-code">resolve(2)</code>。</div><div class="notion-text notion-block-a9f0b5fbc0e74e1f97e958211f11b030"><b>3.4 题目四</b></div><div class="notion-text notion-block-f4516c955957407dab4ec900122e91a6">如果把<code class="notion-inline-code">3.3</code>中的<code class="notion-inline-code">Promise.resolve(1)</code>改为<code class="notion-inline-code">Promise.reject(1)</code>又会怎么样呢？</div><div class="notion-text notion-block-93161e82eb864210bae0e9f9973cc7d5">结果：</div><div class="notion-text notion-block-6aff2ec5b6414c84934b528be7264fe6">结果打印的当然是 <code class="notion-inline-code">1 和 3</code>啦，因为<code class="notion-inline-code">reject(1)</code>此时走的就是<code class="notion-inline-code">catch</code>，且第二个<code class="notion-inline-code">then</code>中的<code class="notion-inline-code">res</code>得到的就是<code class="notion-inline-code">catch</code>中的返回值。</div><div class="notion-text notion-block-ab2ada08237a4ea9ade691a31b7eff6f"><b>3.5 题目五</b></div><div class="notion-text notion-block-bcc38fce89dc4548a494c3a2f1d0dcc6">执行结果：</div><div class="notion-text notion-block-b8d233ef4df842b4b0d47e1cab62043b">当然，如果你足够快的话，也可能两个都是<code class="notion-inline-code">1001</code>。</div><div class="notion-text notion-block-a9007a20e652484c8e84831ae937ed47"><code class="notion-inline-code">Promise</code> 的 <code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 可以被调用多次，但这里 <code class="notion-inline-code">Promise</code> 构造函数只执行一次。或者说 <code class="notion-inline-code">promise</code> 内部状态一经改变，并且有了一个值，那么后续每次调用 <code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 都会直接拿到该值。</div><div class="notion-text notion-block-eb3fd287fdb749829cf35ce0b3b73077"><b>3.6 题目六</b></div><div class="notion-text notion-block-4813523e76a047bbb2554ee8eed18f78">猜猜这里的结果输出的是什么 🤔️ ？</div><div class="notion-text notion-block-f18276ccb56447b7bd7f5455893bd70d">你可能想到的是进入<code class="notion-inline-code">.catch</code>然后被捕获了错误。</div><div class="notion-text notion-block-a733cfcc4aa94e1889a3cd5c9b545358">结果并不是这样的，它走的是<code class="notion-inline-code">.then</code>里面：</div><div class="notion-text notion-block-88e0ad49fe92453da829f3e0ac2ee35d">这也验证了第4点和第6点，返回任意一个非 <code class="notion-inline-code">promise</code> 的值都会被包裹成 <code class="notion-inline-code">promise</code> 对象，因此这里的<code class="notion-inline-code">return new Error(&#x27;error!!!&#x27;)</code>也被包裹成了<code class="notion-inline-code">return Promise.resolve(new Error(&#x27;error!!!&#x27;))</code>。</div><div class="notion-text notion-block-daecfd1f3b0846288d59af8d494a63a3">当然如果你抛出一个错误的话，可以用下面👇两的任意一种：</div><div class="notion-text notion-block-fba5d2bf4a7949c2858b335fe33c52bc"><b>3.7 题目七</b></div><div class="notion-text notion-block-b0f4c3101ed84234a05911afb899807c"><code class="notion-inline-code">.then</code> 或 <code class="notion-inline-code">.catch</code> 返回的值不能是 promise 本身，否则会造成死循环。</div><div class="notion-text notion-block-19e7790303e3447bab025a11da91ce01">因此结果会报错：</div><div class="notion-text notion-block-b16270fa41064bd29eece17878955698"><b>3.8 题目八</b></div><div class="notion-text notion-block-fc6370daa62a45f283f13f09686f30e7">其实你只要记住<b>原则8</b>：<code class="notion-inline-code">.then</code> 或者 <code class="notion-inline-code">.catch</code> 的参数期望是函数，传入非函数则会发生值透传。</div><div class="notion-text notion-block-1bbfba28fb314476a04188b26b961eb6">第一个<code class="notion-inline-code">then</code>和第二个<code class="notion-inline-code">then</code>中传入的都不是函数，一个是数字类型，一个是对象类型，因此发生了透传，将<code class="notion-inline-code">resolve(1)</code> 的值直接传到最后一个<code class="notion-inline-code">then</code>里。</div><div class="notion-text notion-block-5f7ca73349c241da888c5cc8b76a5773">所以输出结果为：</div><div class="notion-text notion-block-41835b176b544999bd0881bc9b6f761a"><b>3.9 题目九</b></div><div class="notion-text notion-block-bd3d4e14955b4e5da304426140c575c4">下面来介绍一下<code class="notion-inline-code">.then</code>函数中的两个参数。</div><div class="notion-text notion-block-12f1375b570e4e2b8993780f694a6a06">第一个参数是用来处理<code class="notion-inline-code">Promise</code>成功的函数，第二个则是处理失败的函数。</div><div class="notion-text notion-block-e520542f95c043a29caaa8a5867a002b">也就是说<code class="notion-inline-code">Promise.resolve(&#x27;1&#x27;)</code>的值会进入成功的函数，<code class="notion-inline-code">Promise.reject(&#x27;2&#x27;)</code>的值会进入失败的函数。</div><div class="notion-text notion-block-03de797d99b54031a43d534da3d6f194">让我们来看看这个例子🌰：</div><div class="notion-text notion-block-1639fd484ead468b81bb28a08605b5a8">结果</div><div class="notion-text notion-block-a458718bfc2f4bef96c9e92fa00f1051">它进入的是<code class="notion-inline-code">then()</code>中的第二个参数里面，而如果把第二个参数去掉，就进入了<code class="notion-inline-code">catch()</code>中：</div><div class="notion-text notion-block-df9aedb65e634675a0d01dba40c9325e">结果</div><div class="notion-text notion-block-3b53dae3c37349cabecb9baf055e3b65">但是有一个问题，如果是这个案例呢？</div><div class="notion-text notion-block-439240ac955d47779a8debdab4dbb355">由于<code class="notion-inline-code">Promise</code>调用的是<code class="notion-inline-code">resolve()</code>，因此<code class="notion-inline-code">.then()</code>执行的应该是<code class="notion-inline-code">success()</code>函数，可是<code class="notion-inline-code">success()</code>函数抛出的是一个错误，它会被后面的<code class="notion-inline-code">catch()</code>给捕获到，而不是被<code class="notion-inline-code">fail1</code>函数捕获。</div><div class="notion-text notion-block-26e87c53e6c34d7a8514b8db66fae81b">因此执行结果为：</div><div class="notion-text notion-block-6a821354497141ac9a38fdfef091c194"><b>3.10 题目十</b></div><div class="notion-text notion-block-283d99de71ed47cc8d9e5bee1da60fed">接着来看看<code class="notion-inline-code">.finally()</code>，这个功能一般不太用在面试中，不过如果碰到了你也应该知道该如何处理。</div><div class="notion-text notion-block-f741a72deb3c4e38877eda8df0b4cfd7">其实你只要记住它三个很重要的知识点就可以了：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3125949dff0b4ad99509b8e110691452"><li><code class="notion-inline-code">.finally()</code>方法不管<code class="notion-inline-code">Promise</code>对象最后的状态如何都会执行</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-251005dcbcf6410b8df6cd395c5bfaea"><li><code class="notion-inline-code">.finally()</code>方法的回调函数不接受任何的参数，也就是说你在<code class="notion-inline-code">.finally()</code>函数中是没法知道<code class="notion-inline-code">Promise</code>最终的状态是<code class="notion-inline-code">resolved</code>还是<code class="notion-inline-code">rejected</code>的</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-addd45e4fdb843d5808e9ee364a44dfa"><li>它最终返回的默认会是一个<b>上一次的Promise对象值</b>，不过如果抛出的是一个异常则返回异常的<code class="notion-inline-code">Promise</code>对象。</li></ol><div class="notion-text notion-block-f6fe5c7a0f07444c8d46e975a47b6847">来看看这个简单的例子🌰：</div><div class="notion-text notion-block-31db2e0b002a432da0f9410d1871bd61">这两个<code class="notion-inline-code">Promise</code>的<code class="notion-inline-code">.finally</code>都会执行，且就算<code class="notion-inline-code">finally2</code>返回了新的值，它后面的<code class="notion-inline-code">then()</code>函数接收到的结果却还是<code class="notion-inline-code">&#x27;2&#x27;</code>，因此打印结果为：</div><div class="notion-text notion-block-682810561db04c0185863a6add6eef40">至于为什么<code class="notion-inline-code">finally2</code>的打印要在<code class="notion-inline-code">finally</code>前面，请看下一个例子中的解析。</div><div class="notion-text notion-block-8d85ea0c92aa46ec9372cc5e36f06b21">不过在此之前让我们再来确认一下，<code class="notion-inline-code">finally</code>中要是抛出的是一个异常是怎样的：</div><div class="notion-text notion-block-8c008e7147b74073b57ffa319b9e2dfe">结果</div><div class="notion-text notion-block-54f9348e578141fda8416535ba118815">但是如果改为<code class="notion-inline-code">return new Error(&#x27;我是finally中抛出的异常&#x27;)</code>，打印出来的就是<code class="notion-inline-code">&#x27;finally后面的then函数 1&#x27;</code></div><div class="notion-text notion-block-1248a543ad4e4d059492bfea1a0a3eff">OK，👌，让我们来看一个比较难的例子🌰：</div><div class="notion-text notion-block-2d9582ef1add4843915e93d0a33478a9">执行过程：</div><ul class="notion-list notion-list-disc notion-block-243a2359194042698413540ae31cd9d6"><li>首先定义了两个函数<code class="notion-inline-code">promise1</code>和<code class="notion-inline-code">promise2</code>，先不管接着往下看。</li></ul><ul class="notion-list notion-list-disc notion-block-33b08430028d4b34b1c7455f658e0160"><li><code class="notion-inline-code">promise1</code>函数先被调用了，然后执行里面<code class="notion-inline-code">new Promise</code>的同步代码打印出<code class="notion-inline-code">promise1</code></li></ul><ul class="notion-list notion-list-disc notion-block-69caf7e80b2f4e4d840973785fa216e4"><li>之后遇到了<code class="notion-inline-code">resolve(1)</code>，将<code class="notion-inline-code">p</code>的状态改为了<code class="notion-inline-code">resolved</code>并将结果保存下来。</li></ul><ul class="notion-list notion-list-disc notion-block-2c668d32bda841c78ae30a412f56e2d1"><li>此时<code class="notion-inline-code">promise1</code>内的函数内容已经执行完了，跳出该函数</li></ul><ul class="notion-list notion-list-disc notion-block-05df91b5d34345ada363c603aaaba55c"><li>碰到了<code class="notion-inline-code">promise1().then()</code>，由于<code class="notion-inline-code">promise1</code>的状态已经发生了改变且为<code class="notion-inline-code">resolved</code>因此将<code class="notion-inline-code">promise1().then()</code>这条微任务加入本轮的微任务列表(<b>这是第一个微任务</b>)</li></ul><ul class="notion-list notion-list-disc notion-block-65e9c78a8edb4ba3ac70d2ed99f6603a"><li>这时候要注意了，代码并不会接着往链式调用的下面走，也就是不会先将<code class="notion-inline-code">.finally</code>加入微任务列表，那是因为<code class="notion-inline-code">.then</code>本身就是一个微任务，它链式后面的内容必须得等当前这个微任务执行完才会执行，因此这里我们先不管<code class="notion-inline-code">.finally()</code></li></ul><ul class="notion-list notion-list-disc notion-block-9a272e0d65f94e7a923312cb1928ea53"><li>再往下走碰到了<code class="notion-inline-code">promise2()</code>函数，其中返回的<code class="notion-inline-code">new Promise</code>中并没有同步代码需要执行，所以执行<code class="notion-inline-code">reject(&#x27;error&#x27;)</code>的时候将<code class="notion-inline-code">promise2</code>函数中的<code class="notion-inline-code">Promise</code>的状态变为了<code class="notion-inline-code">rejected</code></li></ul><ul class="notion-list notion-list-disc notion-block-522c9023ce49449b90cff22d956a5332"><li>跳出<code class="notion-inline-code">promise2</code>函数，遇到了<code class="notion-inline-code">promise2().catch()</code>，将其加入当前的微任务队列(<b>这是第二个微任务</b>)，且链式调用后面的内容得等该任务执行完后才执行，和<code class="notion-inline-code">.then()</code>一样。</li></ul><ul class="notion-list notion-list-disc notion-block-788bae7aaf994b1f9f5fb329f3606097"><li>OK， 本轮的宏任务全部执行完了，来看看微任务列表，存在<code class="notion-inline-code">promise1().then()</code>，执行它，打印出<code class="notion-inline-code">1</code>，然后遇到了<code class="notion-inline-code">.finally()</code>这个微任务将它加入微任务列表(<b>这是第三个微任务</b>)等待执行</li></ul><ul class="notion-list notion-list-disc notion-block-e7f8a12fc99c492e9955de6d2ad2e697"><li>再执行<code class="notion-inline-code">promise2().catch()</code>打印出<code class="notion-inline-code">error</code>，执行完后将<code class="notion-inline-code">finally2</code>加入微任务加入微任务列表(<b>这是第四个微任务</b>)</li></ul><ul class="notion-list notion-list-disc notion-block-1f2b242c27f34e40a75f5dd9ac4776c5"><li>OK， 本轮又全部执行完了，但是微任务列表还有两个新的微任务没有执行完，因此依次执行<code class="notion-inline-code">finally1</code>和<code class="notion-inline-code">finally2</code>。</li></ul><div class="notion-text notion-block-345ee7c3ab624a12a4d38989e1294875">结果：</div><div class="notion-text notion-block-eaef6a7ab7704027928fb77be9781cc5">在这道题中其实能拓展的东西挺多的，之前没有提到，那就是你可以理解为<b>链式调用</b>后面的内容需要等前一个调用执行完才会执行。</div><div class="notion-text notion-block-689f7d1d1efb4867bd3ab4aafbf2bb3a">就像是这里的<code class="notion-inline-code">finally()</code>会等<code class="notion-inline-code">promise1().then()</code>执行完才会将<code class="notion-inline-code">finally()</code>加入微任务队列，其实如果这道题中你把<code class="notion-inline-code">finally()</code>换成是<code class="notion-inline-code">then()</code>也是这样的:</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-2320c463db9c4fbb91f521f5ca7eb4ae" data-id="2320c463db9c4fbb91f521f5ca7eb4ae"><span><div id="2320c463db9c4fbb91f521f5ca7eb4ae" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2320c463db9c4fbb91f521f5ca7eb4ae" title="4. Promise中的all和race"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>4. Promise中的all和race</b></span></span></h4><div class="notion-text notion-block-66d489a5f57c485dbd918634a76e562a">在做下面👇的题目之前，让我们先来了解一下<code class="notion-inline-code">Promise.all()</code>和<code class="notion-inline-code">Promise.race()</code>的用法。</div><div class="notion-text notion-block-15eed127256c4188ac1a8826b1354fd7">通俗来说，<code class="notion-inline-code">.all()</code>的作用是接收一组异步任务，然后并行执行异步任务，并且在所有异步操作执行完后才执行回调。</div><div class="notion-text notion-block-6a565da8334440118d66fcee454893b7"><code class="notion-inline-code">.race()</code>的作用也是接收一组异步任务，然后并行执行异步任务，只保留取第一个执行完成的异步操作的结果，其他的方法仍在执行，不过执行结果会被抛弃。</div><div class="notion-text notion-block-33f39bab8a2749769c1ef61f98b558d5"><b>4.1 题目一</b></div><div class="notion-text notion-block-c392af0c576f478f87bf4a70658effed">我们知道如果直接在脚本文件中定义一个<code class="notion-inline-code">Promise</code>，它构造函数的第一个参数是会立即执行的，就像这样：</div><div class="notion-text notion-block-04b05b36772c46328c0f8b4b6750fa3e">控制台中会立即打印出 “立即打印”。</div><div class="notion-text notion-block-0710659eb0e244aa9db2626100768a29">因此为了控制它什么时候执行，我们可以用一个函数包裹着它，在需要它执行的时候，调用这个函数就可以了：</div><div class="notion-text notion-block-dd00ba59efc34fa4949173e9dd3fe447">OK 👌， 让我们回归正题。</div><div class="notion-text notion-block-43713db64a054124be0087bb04c68f5f">现在来构建这么一个函数：</div><div class="notion-text notion-block-4f67d8c1b0f949e9ad7b4d42c4319446">该函数传入一个值<code class="notion-inline-code">x</code>，然后间隔一秒后打印出这个<code class="notion-inline-code">x</code>。</div><div class="notion-text notion-block-81d060ab417a4f5299f75e1675c44e17">如果我用<code class="notion-inline-code">.all()</code>来执行它会怎样呢？</div><div class="notion-text notion-block-4399e6bab42a4051a01702b25d928bad">先来想想此段代码在浏览器中会如何执行？</div><div class="notion-text notion-block-35113e9c476b4ebbb55eec1ac690bf8c">没错，当你打开页面的时候，在间隔一秒后，控制台会同时打印出<code class="notion-inline-code">1, 2, 3</code>，还有一个数组<code class="notion-inline-code">[1, 2, 3]</code>。</div><div class="notion-text notion-block-61df3ad6b9be45cd85e6eb9c435b4461">所以你现在能理解这句话的意思了吗：<b>有了all，你就可以并行执行多个异步操作，并且在一个回调中处理所有的返回数据。</b></div><div class="notion-text notion-block-5a4099726e9b4a3db66b9259b9753531"><code class="notion-inline-code">.all()</code>后面的<code class="notion-inline-code">.then()</code>里的回调函数接收的就是所有异步操作的结果。</div><div class="notion-text notion-block-a63ee38978bf460ca9c9ecaab2b85089">而且这个结果中数组的顺序和<code class="notion-inline-code">Promise.all()</code>接收到的数组顺序一致！！！</div><div class="notion-text notion-block-d0b1cf2dd317490da31d5e8755ee3db4">有一个场景是很适合用这个的，一些游戏类的素材比较多的应用，打开网页时，预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后，我们再进行页面的初始化。</div><div class="notion-text notion-block-82b68ff61726421eb38f71ad5599af7f"><b>4.2 题目二</b></div><div class="notion-text notion-block-698b738d0f804b59b0954ac74009db1f">我新增了一个<code class="notion-inline-code">runReject</code>函数，它用来在<code class="notion-inline-code">1000 * x</code>秒后<code class="notion-inline-code">reject</code>一个错误。</div><div class="notion-text notion-block-5d0d058ced6c4cc5a7fd535589c2ef80">同时<code class="notion-inline-code">.catch()</code>函数能够捕获到<code class="notion-inline-code">.all()</code>里最先的那个异常，并且只执行一次。</div><div class="notion-text notion-block-57cd24218a314823bb46eae96f8d4732">想想这道题会怎样执行呢 🤔️？</div><div class="notion-text notion-block-ae2a2fadd3a843519dfa09519a934375">结果</div><div class="notion-text notion-block-425b1dda2d8e4ad6942253b13cc74755">没错，就像我之前说的，<code class="notion-inline-code">.catch</code>是会捕获最先的那个异常，在这道题目中最先的异常就是<code class="notion-inline-code">runReject(2)</code>的结果。</div><div class="notion-text notion-block-b72f694b958f42579ec3d6522f2e2a3b">另外，如果一组异步操作中有一个异常都不会进入<code class="notion-inline-code">.then()</code>的第一个回调函数参数中。</div><div class="notion-text notion-block-d9fceba31c4f47b885fff1356289a62f">注意，为什么不说是不进入<code class="notion-inline-code">.then()</code>中呢 🤔️？</div><div class="notion-text notion-block-a57e0d51598d45498eeb35d6f6fd4637">哈哈，大家别忘了<code class="notion-inline-code">.then()</code>方法的第二个参数也是可以捕获错误的：</div><div class="notion-text notion-block-46041faedc2148e5b3e2e88825edca5d"><b>4.3 题目三</b></div><div class="notion-text notion-block-c948a0ff1be54e39a82f5b3f83543095"><code class="notion-inline-code">race</code>，比赛，赛跑的意思。</div><div class="notion-text notion-block-bafa35c3b9bd45c88b1f0c130d932b00">所以使用<code class="notion-inline-code">.race()</code>方法，它只会获取最先执行完成的那个结果，其它的异步任务虽然也会继续进行下去，不过<code class="notion-inline-code">race</code>已经不管那些任务的结果了。</div><div class="notion-text notion-block-b91493ba549e466aae86028e89c7cd8e">来，改造一下<code class="notion-inline-code">4.1</code>这道题：</div><div class="notion-text notion-block-44acd1cc188c4d669ede3cffd812035d">结果:</div><div class="notion-text notion-block-76728ad511984659bc60f7452f1d3c96"><b>4.4 题目四</b></div><div class="notion-text notion-block-47e26ee5eaf04839a3dcbe2f907b6b29">遇到错误的话，也是一样的，在这道题中，<code class="notion-inline-code">runReject(0)</code>最先执行完，所以进入了<code class="notion-inline-code">catch()</code>中：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-9dbd16a11cfa44918a3146907453ca16" data-id="9dbd16a11cfa44918a3146907453ca16"><span><div id="9dbd16a11cfa44918a3146907453ca16" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9dbd16a11cfa44918a3146907453ca16" title="总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">总结</span></span></h4><div class="notion-text notion-block-7ec5469fc06649e6acdd9ff2f88c47ec">好的，让我们来总结一下<code class="notion-inline-code">.then()</code>和<code class="notion-inline-code">.race()</code>吧，😄</div><ul class="notion-list notion-list-disc notion-block-130b1b96a574431b9330191cccc82f1c"><li><code class="notion-inline-code">Promise.all()</code>的作用是接收一组异步任务，然后并行执行异步任务，并且在所有异步操作执行完后才执行回调。</li></ul><ul class="notion-list notion-list-disc notion-block-1ddca917bcc140afb502f9938731eaf0"><li><code class="notion-inline-code">.race()</code>的作用也是接收一组异步任务，然后并行执行异步任务，只保留取第一个执行完成的异步操作的结果，其他的方法仍在执行，不过执行结果会被抛弃。</li></ul><ul class="notion-list notion-list-disc notion-block-acd963077ac04fb49f630f17584b4ef4"><li><code class="notion-inline-code">Promise.all().then()</code>结果中数组的顺序和<code class="notion-inline-code">Promise.all()</code>接收到的数组顺序一致。</li></ul><ul class="notion-list notion-list-disc notion-block-ee4254260b9a47ba97ac64199451f075"><li><code class="notion-inline-code">all和race</code>传入的数组中如果有会抛出异常的异步任务，那么只有最先抛出的错误会被捕获，并且是被<code class="notion-inline-code">then</code>的第二个参数或者后面的<code class="notion-inline-code">catch</code>捕获；但并不会影响数组中其它的异步任务的执行。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4edc8c3511a145539913fdf94cb4b6d1" data-id="4edc8c3511a145539913fdf94cb4b6d1"><span><div id="4edc8c3511a145539913fdf94cb4b6d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4edc8c3511a145539913fdf94cb4b6d1" title="5. async/await的几道题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>5. async/await的几道题</b></span></span></h4><div class="notion-text notion-block-03514226d6464bd4a58ecb3a89e1e329"><b>5.1 题目一</b></div><div class="notion-text notion-block-58b5982d4e1e4cdea70cd0bd2f921e87">答案</div><div class="notion-text notion-block-3214866c0ffb4130b0942e5b7a9017df">过程分析：</div><ul class="notion-list notion-list-disc notion-block-a39b35baabc747e586fb8d9cf5bf44bc"><li>首先一进来是创建了两个函数的，我们先不看函数的创建位置，而是看它的调用位置</li></ul><ul class="notion-list notion-list-disc notion-block-82f4957a198f4cafa269bc2ae234e7b8"><li>发现<code class="notion-inline-code">async1</code>函数被调用了，然后去看看调用的内容</li></ul><ul class="notion-list notion-list-disc notion-block-5463da7ca1aa490da36d671e6a98c4c8"><li>执行函数中的同步代码<code class="notion-inline-code">async1 start</code>，之后碰到了<code class="notion-inline-code">await</code>，它会阻塞<code class="notion-inline-code">async1</code>后面代码的执行，因此会先去执行<code class="notion-inline-code">async2</code>中的同步代码<code class="notion-inline-code">async2</code>，然后跳出<code class="notion-inline-code">async1</code></li></ul><ul class="notion-list notion-list-disc notion-block-279dfef67b98451fa85f45a39f5f3e01"><li>跳出<code class="notion-inline-code">async1</code>函数后，执行同步代码<code class="notion-inline-code">start</code></li></ul><ul class="notion-list notion-list-disc notion-block-dabf08217d7345a0aa0051b19bfe63aa"><li>在一轮宏任务全部执行完之后，再来执行刚刚<code class="notion-inline-code">await</code>后面的内容<code class="notion-inline-code">async1 end</code>。</li></ul><div class="notion-text notion-block-ff4d7302649b4816a0466620640d4a70">在这里，你可以理解为「紧跟着await后面的语句相当于放到了new Promise中，下一行及之后的语句相当于放在Promise.then中」。</div><div class="notion-text notion-block-0d45d45d3e614e2b83c596301bb33060">让我们来看看将<code class="notion-inline-code">await</code>转换为<code class="notion-inline-code">Promise.then</code>的伪代码：</div><div class="notion-text notion-block-9918dca820394debb0e0337bfc0bf9be">转换后的伪代码和前面的执行结果是一样的。(感谢评论区<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/user/3421335914314061">Wing93</a>和<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/user/1926000100012317">Jexxie</a>小伙伴的指出)</div><div class="notion-text notion-block-3ba68016b3bc40b384ec34c8df6dac7b">另外关于<code class="notion-inline-code">await</code>和<code class="notion-inline-code">Promise</code>的区别，如果我们把<code class="notion-inline-code">await async2()</code>换成一个<code class="notion-inline-code">new Promise</code>呢？</div><div class="notion-text notion-block-076b1b3bddcf4921aa9a4779ce3dbb4d">结果</div><div class="notion-text notion-block-b26e2fa8e284406d9245c4c3d72e392c">可以看到<code class="notion-inline-code">new Promise()</code>并不会阻塞后面的同步代码<code class="notion-inline-code">async1 end</code>的执行。</div><div class="notion-text notion-block-6a26d27a2cef49029bca59f06782837c"><b>5.2 题目二</b></div><div class="notion-text notion-block-a2f70591dc0b4dcf92f6db4e9a75102c">现在将<code class="notion-inline-code">async</code>结合定时器看看。</div><div class="notion-text notion-block-8d29a3e0641a4c6cb28aadd06a74e36e">给题目一中的 <code class="notion-inline-code">async2</code>函数中加上一个定时器：</div><div class="notion-text notion-block-6d3a7a0c5b664b3daff91f61ca49fefe">没错，定时器始终还是最后执行的，它被放到下一条宏任务的延迟队列中。</div><div class="notion-text notion-block-f48944fc12f24439b4ad92ecd8a6bf48">答案：</div><div class="notion-text notion-block-81c217fab0db4c30930cb8af586a9f0d"><b>5.3 题目三</b></div><div class="notion-text notion-block-58dd8075d2ef41c9940c128e18d1e66b">来吧，小伙伴们，让我们多加几个定时器看看。😁</div><div class="notion-text notion-block-9dcb841f4c2a4afab3cb6dbd53821bc4">思考一下🤔，执行结果会是什么？</div><div class="notion-text notion-block-67a9cf38a2c746c79583944899abc7b4">其实如果你能做到这里了，说明你前面的那些知识点也都掌握了，我就不需要太过详细的步骤分析了。</div><div class="notion-text notion-block-5d3535b8b86545ee87e7298537be541b">直接公布答案吧：</div><div class="notion-text notion-block-0ba60ad7c6ea4808808ae630e7db313b">定时器谁先执行，你只需要关注谁先被调用的以及延迟时间是多少，这道题中延迟时间都是<code class="notion-inline-code">0</code>，所以只要关注谁先被调用的。</div><div class="notion-text notion-block-6e7224b541fa4adda2bb957a32e78d27"><b>5.4 题目四</b></div><div class="notion-text notion-block-386fe7bc55bd4c9e96f4a4b836925bc5">正常情况下，<code class="notion-inline-code">async</code>中的<code class="notion-inline-code">await</code>命令是一个<code class="notion-inline-code">Promise</code>对象，返回该对象的结果。</div><div class="notion-text notion-block-00718f31c60143ecbb96512c3a1b7fa4">但如果不是<code class="notion-inline-code">Promise</code>对象的话，就会直接返回对应的值，相当于<code class="notion-inline-code">Promise.resolve()</code></div><div class="notion-text notion-block-b9099e38124d4d6396e6bab7a9b265bb"><b>5.5 题目五</b></div><div class="notion-text notion-block-ddd9dbaed71e448fbd0fe7f4630760d3">这道题目比较有意思，大家要注意了。</div><div class="notion-text notion-block-69d8551cce0c4aaa9e6f50a83f67b2f7">在<code class="notion-inline-code">async1</code>中<code class="notion-inline-code">await</code>后面的<code class="notion-inline-code">Promise</code>是没有返回值的，也就是它的状态始终是<code class="notion-inline-code">pending</code>状态，因此相当于一直在<code class="notion-inline-code">await</code>，<code class="notion-inline-code">await</code>，<code class="notion-inline-code">await</code>却始终没有响应...</div><div class="notion-text notion-block-a3b8db6a58e347f5908b82e949aadaa2">答案</div><div class="notion-text notion-block-b92c4be656f244eaa0328eff0396db4c"><b>5.6 题目六</b></div><div class="notion-text notion-block-587dbcebe85b47a9a9d38e2a9e47ab30">让我们给<code class="notion-inline-code">5.5</code>中的<code class="notion-inline-code">Promise</code>加上<code class="notion-inline-code">resolve</code>：</div><div class="notion-text notion-block-4283b37c9d6e46a2bf482a98d61e773c">现在<code class="notion-inline-code">Promise</code>有了返回值了，因此<code class="notion-inline-code">await</code>后面的内容将会被执行：</div><div class="notion-text notion-block-8f7aef78217d415999e7913606fcf13b"><b>5.7 题目七</b></div><div class="notion-text notion-block-5ae293f0566e42b8bf8b67ec7ed27a19">这道题应该也不难，不过有一点需要注意的，在<code class="notion-inline-code">async1</code>中的<code class="notion-inline-code">new Promise</code>它的<code class="notion-inline-code">resovle</code>的值和<code class="notion-inline-code">async1().then()</code>里的值是没有关系的，很多小伙伴可能看到<code class="notion-inline-code">resovle(&#x27;promise resolve&#x27;)</code>就会误以为是<code class="notion-inline-code">async1().then()</code>中的返回值。</div><div class="notion-text notion-block-50d9d9c7ae194b11b73cfa9c1d40c8b9">因此这里的执行结果为：</div><div class="notion-text notion-block-08501375c99a4264a783c891dee38f52"><b>5.8 题目八</b></div><div class="notion-text notion-block-2bafbfd2da3744008aa0736b5c4f3d56">我们再来看一道头条曾经的面试题：</div><div class="notion-text notion-block-3123e6e4a95f4690b2423f325ffcca85">答案</div><div class="notion-text notion-block-593578aab9294132a2c9170fed4c3d12">(这道题最后<code class="notion-inline-code">async1 end</code>和<code class="notion-inline-code">promise2</code>的顺序其实在网上饱受争议，我这里使用浏览器<code class="notion-inline-code">Chrome V80</code>，<code class="notion-inline-code">Node v12.16.1</code>的执行结果都是上面这个答案)</div><div class="notion-text notion-block-239c9d6a41dd4ca2836eebc5e756331a"><b>5.9 题目九</b></div><div class="notion-text notion-block-ac53d4f19d224a6ab3e167c4089c99ed">答案</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-b245618835a84aa8bcc491f9d7879926" data-id="b245618835a84aa8bcc491f9d7879926"><span><div id="b245618835a84aa8bcc491f9d7879926" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b245618835a84aa8bcc491f9d7879926" title="6. async处理错误"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>6. async处理错误</b></span></span></h4><div class="notion-text notion-block-c6f69b769b044315bc09ecdea0740ec2"><b>6.1 题目一</b></div><div class="notion-text notion-block-11ed5e20847842759777289418e9bcbf">在<code class="notion-inline-code">async</code>中，如果 <code class="notion-inline-code">await</code>后面的内容是一个异常或者错误的话，会怎样呢？</div><div class="notion-text notion-block-73b4e1498d0c4aa48e083a0b4ad4ae97">例如这道题中，<code class="notion-inline-code">await</code>后面跟着的是一个状态为<code class="notion-inline-code">rejected</code>的<code class="notion-inline-code">promise</code>。</div><div class="notion-text notion-block-ad41769f9d86468bae6fbc0a7f746bf3"><b>如果在async函数中抛出了错误，则终止错误结果，不会继续向下执行。</b></div><div class="notion-text notion-block-d88747e6bd234c4aa5f83c3734e96f9d">所以答案为：</div><div class="notion-text notion-block-27e1bdcbe75049cd8b533f61ac7908b4">如果改为<code class="notion-inline-code">throw new Error</code>也是一样的：</div><div class="notion-text notion-block-75ad4f2ba56e4058aa78fca9e2ac34fa">结果</div><div class="notion-text notion-block-b1d0a98b46444009bf98a041aefe6143"><b>6.2 题目二</b></div><div class="notion-text notion-block-8e465984c3914dba9dca22430a4f63b4">如果想要使得错误的地方不影响<code class="notion-inline-code">async</code>函数后续的执行的话，可以使用<code class="notion-inline-code">try catch</code></div><div class="notion-text notion-block-dfa43983ab5f4c3d9b4d47f4f7a2e728">⇒</div><div class="notion-text notion-block-c573bcdd45cb4acc8600883629e31ffa">或者你可以直接在<code class="notion-inline-code">Promise.reject</code>后面跟着一个<code class="notion-inline-code">catch()</code>方法：</div><div class="notion-text notion-block-f0ab303294504288ac9a9f638b818ae0">结果一样</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-c5c85716ca8046d9afeccb8eb5aa94bc" data-id="c5c85716ca8046d9afeccb8eb5aa94bc"><span><div id="c5c85716ca8046d9afeccb8eb5aa94bc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c5c85716ca8046d9afeccb8eb5aa94bc" title="7. 综合题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>7. 综合题</b></span></span></h4><div class="notion-text notion-block-c0f38b97419b4788a79701a3bfc241db"><b>7.1 题目一</b></div><div class="notion-text notion-block-d76d620a4b5c4e01ab0244371d55540f">过程分析：</div><ul class="notion-list notion-list-disc notion-block-853c3a7ba7fa4d608433b4b0cbe8cd9b"><li>第一段代码定义的是一个函数，所以我们得看看它是在哪执行的，发现它在<code class="notion-inline-code">4</code>之前，所以可以来看看<code class="notion-inline-code">first</code>函数里面的内容了。(这一步有点类似于题目<code class="notion-inline-code">1.5</code>)</li></ul><ul class="notion-list notion-list-disc notion-block-a605b8d87f844ac097395bd65df5dfb3"><li>函数<code class="notion-inline-code">first</code>返回的是一个<code class="notion-inline-code">new Promise()</code>，因此先执行里面的同步代码<code class="notion-inline-code">3</code></li></ul><ul class="notion-list notion-list-disc notion-block-b5be8ceabe084ae0b28bd1ee2d579366"><li>接着又遇到了一个<code class="notion-inline-code">new Promise()</code>，直接执行里面的同步代码<code class="notion-inline-code">7</code></li></ul><ul class="notion-list notion-list-disc notion-block-e2c9f077afdd47de870e8a926f1b5fff"><li>执行完<code class="notion-inline-code">7</code>之后，在<code class="notion-inline-code">p</code>中，遇到了一个定时器，先将它放到下一个宏任务队列里不管它，接着向下走</li></ul><ul class="notion-list notion-list-disc notion-block-fb64f6feea8e4aadbae791003fa54885"><li>碰到了<code class="notion-inline-code">resolve(1)</code>，这里就把<code class="notion-inline-code">p</code>的状态改为了<code class="notion-inline-code">resolved</code>，且返回值为<code class="notion-inline-code">1</code>，不过这里也先不执行</li></ul><ul class="notion-list notion-list-disc notion-block-bd3ccf961b5742088b42abf8275a52d3"><li>跳出<code class="notion-inline-code">p</code>，碰到了<code class="notion-inline-code">resolve(2)</code>，这里的<code class="notion-inline-code">resolve(2)</code>，表示的是把<code class="notion-inline-code">first</code>函数返回的那个<code class="notion-inline-code">Promise</code>的状态改了，也先不管它。</li></ul><ul class="notion-list notion-list-disc notion-block-76f826d9da964f24945aa5017e8cdaa5"><li>然后碰到了<code class="notion-inline-code">p.then</code>，将它加入本次循环的微任务列表，等待执行</li></ul><ul class="notion-list notion-list-disc notion-block-32e8a0c60bc54b0d99755fcbfc583e2f"><li>跳出<code class="notion-inline-code">first</code>函数，遇到了<code class="notion-inline-code">first().then()</code>，将它加入本次循环的微任务列表(<code class="notion-inline-code">p.then</code>的后面执行)</li></ul><ul class="notion-list notion-list-disc notion-block-02531b729cbc4af4b68d90257c84c80a"><li>然后执行同步代码<code class="notion-inline-code">4</code></li></ul><ul class="notion-list notion-list-disc notion-block-4308eb415f544940873ac02f4dc6ad2f"><li>本轮的同步代码全部执行完毕，查找微任务列表，发现<code class="notion-inline-code">p.then</code>和<code class="notion-inline-code">first().then()</code>，依次执行，打印出<code class="notion-inline-code">1和2</code></li></ul><ul class="notion-list notion-list-disc notion-block-7d648ac72b214ebc84081c3306d9c178"><li>本轮任务执行完毕了，发现还有一个定时器没有跑完，接着执行这个定时器里的内容，执行同步代码<code class="notion-inline-code">5</code></li></ul><ul class="notion-list notion-list-disc notion-block-7e8f9b33c0b244bc89612d6c53408ddf"><li>然后又遇到了一个<code class="notion-inline-code">resolve(6)</code>，它是放在<code class="notion-inline-code">p</code>里的，但是<code class="notion-inline-code">p</code>的状态在之前已经发生过改变了，因此这里就不会再改变，也就是说<code class="notion-inline-code">resolve(6)</code>相当于没任何用处，因此打印出来的<code class="notion-inline-code">p</code>为<code class="notion-inline-code">Promise{&lt;resolved&gt;: 1}</code>。(这一步类似于题目<code class="notion-inline-code">3.1</code>)</li></ul><div class="notion-text notion-block-20bc2846d8cb47fb8bde2ed56f324f9b">结果：</div><div class="notion-text notion-block-7157b574cbee402ab94a753e9ec05701"><b>7.2 题目二</b></div><div class="notion-text notion-block-6ab90c92053040ff92cafc9eb272a576">注意的知识点：</div><ul class="notion-list notion-list-disc notion-block-abe77b518e024bfd87c12d28e61d988e"><li><code class="notion-inline-code">async</code>函数中<code class="notion-inline-code">await</code>的<code class="notion-inline-code">new Promise</code>要是没有返回值的话则不执行后面的内容(类似题<code class="notion-inline-code">5.5</code>)</li></ul><ul class="notion-list notion-list-disc notion-block-580c2931d88a4f8fb6cb9d4104560c7a"><li><code class="notion-inline-code">.then</code>函数中的参数期待的是函数，如果不是函数的话会发生透传(类似题<code class="notion-inline-code">3.8</code> )</li></ul><ul class="notion-list notion-list-disc notion-block-87f7a106f7e54690a296e78b93eef2ef"><li>注意定时器的延迟时间</li></ul><div class="notion-text notion-block-92022181dfde4684af22b3966a2a04f6">因此本题答案为：</div><div class="notion-text notion-block-d5997333a7434b11b980291ba80f739c"><b>7.3 题目三</b></div><div class="notion-text notion-block-c321fcd02bfb48c9955f31cd94c33931">注意的知识点：</div><ul class="notion-list notion-list-disc notion-block-7ea6d86dde5748f99cfcb40c5a45d2be"><li><code class="notion-inline-code">Promise</code>的状态一旦改变就无法改变(类似题目<code class="notion-inline-code">3.5</code>)</li></ul><ul class="notion-list notion-list-disc notion-block-08d19eeb5b39463688fd271e36a6e3e9"><li><code class="notion-inline-code">finally</code>不管<code class="notion-inline-code">Promise</code>的状态是<code class="notion-inline-code">resolved</code>还是<code class="notion-inline-code">rejected</code>都会执行，且它的回调函数是接收不到<code class="notion-inline-code">Promise</code>的结果的，所以<code class="notion-inline-code">finally()</code>中的<code class="notion-inline-code">res</code>是一个迷惑项(类似<code class="notion-inline-code">3.10</code>)。</li></ul><ul class="notion-list notion-list-disc notion-block-028a9e4bf63547aeaa7ca7038e573fb5"><li>最后一个定时器打印出的<code class="notion-inline-code">p1</code>其实是<code class="notion-inline-code">.finally</code>的返回值，我们知道<code class="notion-inline-code">.finally</code>的返回值如果在没有抛出错误的情况下默认会是上一个<code class="notion-inline-code">Promise</code>的返回值(<code class="notion-inline-code">3.10</code>中也有提到), 而这道题中<code class="notion-inline-code">.finally</code>上一个<code class="notion-inline-code">Promise</code>是<code class="notion-inline-code">.then()</code>，但是这个<code class="notion-inline-code">.then()</code>并没有返回值，所以<code class="notion-inline-code">p1</code>打印出来的<code class="notion-inline-code">Promise</code>的值会是<code class="notion-inline-code">undefined</code>，如果你在定时器的<b>下面</b>加上一个<code class="notion-inline-code">return 1</code>，则值就会变成<code class="notion-inline-code">1</code>(感谢掘友<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/user/2260251637193639">JS丛中过</a>的指出)。</li></ul><div class="notion-text notion-block-18cedddd975a44c9916286cc6abbf26f">答案：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-25097d73bedd450684c6e61733bcb7d6" data-id="25097d73bedd450684c6e61733bcb7d6"><span><div id="25097d73bedd450684c6e61733bcb7d6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#25097d73bedd450684c6e61733bcb7d6" title="8. 几道大厂的面试题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>8. 几道大厂的面试题</b></span></span></h4><div class="notion-text notion-block-09449d7aede142199b37151300e71da6"><b>8.1 使用Promise实现每隔1秒输出1,2,3</b></div><div class="notion-text notion-block-9057d242151641238a15e65b4d5457e9">这道题比较简单的一种做法是可以用<code class="notion-inline-code">Promise</code>配合着<code class="notion-inline-code">reduce</code>不停的在<code class="notion-inline-code">promise</code>后面叠加<code class="notion-inline-code">.then</code>，请看下面的代码：</div><div class="notion-text notion-block-35e47e37ec7c4e16abe9b628a6342fa8">或者你可以更简单一点写：</div><div class="notion-text notion-block-1293846949044674b7c6d0fd0dbcb103"><b>8.2 使用Promise实现红绿灯交替重复亮</b></div><div class="notion-text notion-block-05a70a918cbe48d89425f8f9548a76d3">红灯3秒亮一次，黄灯2秒亮一次，绿灯1秒亮一次；如何让三个灯不断交替重复亮灯？（用Promise实现）三个亮灯函数已经存在：</div><div class="notion-text notion-block-6979e16f889d4084ae2cd3aa2f186128">⇒</div><div class="notion-text notion-block-62cf70ed6f5341f3b38debecb2876eb3"><b>8.3 实现mergePromise函数</b></div><div class="notion-text notion-block-654fadf1e5da4e6b8807a7f3ad41a017">实现mergePromise函数，把传进去的数组按顺序先后执行，并且把返回的数据先后放到数组data中。</div><div class="notion-text notion-block-a8027e7c6c5b4d9e9da15b96c43e44cd">这道题有点类似于<code class="notion-inline-code">Promise.all()</code>，不过<code class="notion-inline-code">.all()</code>不需要管执行顺序，只需要并发执行就行了。但是这里需要等上一个执行完毕之后才能执行下一个。</div><div class="notion-text notion-block-f355bb49d2fa4edc8b1acd3c51cc7996">解题思路：</div><ul class="notion-list notion-list-disc notion-block-7f60b3f2c0184d028161e23ca425742a"><li>定义一个数组<code class="notion-inline-code">data</code>用于保存所有异步操作的结果</li></ul><ul class="notion-list notion-list-disc notion-block-cc25e9d47b4f421b97fb2f02ad29f3b6"><li>初始化一个<code class="notion-inline-code">const promise = Promise.resolve()</code>，然后循环遍历数组，在<code class="notion-inline-code">promise</code>后面添加执行<code class="notion-inline-code">ajax</code>任务，同时要将添加的结果重新赋值到<code class="notion-inline-code">promise</code>上。</li></ul><div class="notion-text notion-block-e0041fe290ae4362bfe73bb1638c37df">答案：</div><div class="notion-text notion-block-3b5c297bfa3e4eaea950f47c143fc1fa"><b>8.4 根据promiseA+实现一个自己的promise</b></div><ul class="notion-list notion-list-disc notion-block-1c38bab68df24dc6b64eafde2992b21c"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/post/6844903607968481287#heading-7">《Promise不会？？看这里！！！史上最通俗易懂的Promise！！！》</a></li></ul><ul class="notion-list notion-list-disc notion-block-d9caeded040d489aa913d30d0b7c7972"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F23312442">《写一个符合 Promises/A+ 规范并可配合 ES7 async/await 使用的 Promise》</a></li></ul><div class="notion-text notion-block-5c4b58184ece43f484470923b21547c2"><b>8.5 封装一个异步加载图片的方法</b></div><div class="notion-text notion-block-335cd7ae8f0f494c8f7c792e07355a46">这个相对简单一些，只需要在图片的<code class="notion-inline-code">onload</code>函数中，使用<code class="notion-inline-code">resolve</code>返回一下就可以了。</div><div class="notion-text notion-block-39806b495bcc4d31aedc2ed123382ca2"><b>8.6 限制异步操作的并发个数并尽可能快的完成全部</b></div><div class="notion-text notion-block-0e0a773827f249f3bcc2917813ecaeda">有8个图片资源的url，已经存储在数组<code class="notion-inline-code">urls</code>中。</div><div class="notion-text notion-block-e5cf9fae2514441b842083783b5aa9ee"><code class="notion-inline-code">urls</code>类似于<code class="notion-inline-code">[&#x27;https://image1.png&#x27;, &#x27;https://image2.png&#x27;, ....]</code></div><div class="notion-text notion-block-914f17e3b8e544b1a84561d42e2f4953">而且已经有一个函数<code class="notion-inline-code">function loadImg</code>，输入一个<code class="notion-inline-code">url</code>链接，返回一个<code class="notion-inline-code">Promise</code>，该<code class="notion-inline-code">Promise</code>在图片下载完成的时候<code class="notion-inline-code">resolve</code>，下载失败则<code class="notion-inline-code">reject</code>。</div><div class="notion-text notion-block-6763e7f2227949f9a261b980d0e7e55b">但有一个要求，任何时刻同时下载的链接<b>数量不可以超过3个</b>。</div><div class="notion-text notion-block-f2f3f29e4b694ce688f4df59e7afe8c8">请写一段代码实现这个需求，要求<b>尽可能快速</b>地将所有图片下载完成。</div><div class="notion-blank notion-block-8c7967eab61a4678aca10583cfa4e836"> </div><div class="notion-text notion-block-a0224407dcee45bfa9cae146a04a4ec8">看到这道题时，我最开始的想法是：</div><ul class="notion-list notion-list-disc notion-block-6551f18b1430464e9d6e28cdefe9a868"><li>拿到<code class="notion-inline-code">urls</code>，然后将这个数组每3个<code class="notion-inline-code">url</code>一组创建成一个二维数组</li></ul><ul class="notion-list notion-list-disc notion-block-60eddd7c83ce4481ae0073119af48f62"><li>然后用<code class="notion-inline-code">Promise.all()</code>每次加载一组<code class="notion-inline-code">url</code>（也就是并发3个），这一组加载完再加载下一组。</li></ul><div class="notion-text notion-block-5b57711ed7e64de7bf1c8e1b64ae6c02">这个想法从技术上说并不难实现，有点类似于第三题。不过缺点也明显，那就是每次都要等到上一组全部加载完之后，才加载下一组，那如果上一组有<code class="notion-inline-code">2</code>个已经加载完了，还有<code class="notion-inline-code">1</code>个特别慢，还在加载，要等这个慢的也加载完才能进入下一组。这明显会照常卡顿，影响加载效率。</div><hr class="notion-hr notion-block-06816504c450435085656a1d1fc91d34"/><div class="notion-text notion-block-d00c130329a040d689ba2cf040a167ea">既然题目的要求是保证每次并发请求的数量为3，那么我们可以先请求<code class="notion-inline-code">urls</code>中的前面三个(下标为<code class="notion-inline-code">0,1,2</code>)，并且请求的时候使用<code class="notion-inline-code">Promise.race()</code>来同时请求，三个中有一个先完成了(例如下标为<code class="notion-inline-code">1</code>的图片)，我们就把这个当前数组中已经完成的那一项(第<code class="notion-inline-code">1</code>项)换成还没有请求的那一项(<code class="notion-inline-code">urls</code>中下标为<code class="notion-inline-code">3</code>)。</div><div class="notion-text notion-block-3814a96656624ce6b22f518e2ffbab67">直到<code class="notion-inline-code">urls</code>已经遍历完了，然后将最后三个没有完成的请求(也就是状态没有改变的<code class="notion-inline-code">Promise</code>)用<code class="notion-inline-code">Promise.all()</code>来加载它们。</div><div class="notion-text notion-block-563f25afb60f428db7c075afaae3a384">不多说，流程图都给你画好了，你可以结合流程图再来看代码。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a2a5312904264f538c0a19fd216d5b50"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F2f0241cb-4f07-4d35-8252-c478d8b88123%2F163120b1-4153-4947-8f43-4e536c630c4f%2FWechatIMG31.jpg?table=block&amp;id=a2a53129-0426-4f53-8c0a-19fd216d5b50" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-05d9dbd94e3347f589459e720b3b432e"> </div><div class="notion-blank notion-block-97294f413e524eb8a5633b2e8ca7d9d0"> </div><div class="notion-blank notion-block-3e9c099d996748d0a8717c665847e4ad"> </div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-c2a95984de8741819b1c12ab49d1f916" data-id="c2a95984de8741819b1c12ab49d1f916"><span><div id="c2a95984de8741819b1c12ab49d1f916" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c2a95984de8741819b1c12ab49d1f916" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h4><ul class="notion-list notion-list-disc notion-block-4c89ce00faa440d8aa658996414053bd"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/post/6844904077537574919">https://juejin.cn/post/6844904077537574919</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[前端开发中常用的js工具函数]]></title>
            <link>https://notionext-three.vercel.app/article/js-utils</link>
            <guid>https://notionext-three.vercel.app/article/js-utils</guid>
            <pubDate>Sat, 11 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[常用js技巧]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-eef9e9c1f2604d86b61e20df61454cc3"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-f2956425e8a6447998c39ef921c3ac00" data-id="f2956425e8a6447998c39ef921c3ac00"><span><div id="f2956425e8a6447998c39ef921c3ac00" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f2956425e8a6447998c39ef921c3ac00" title="开发中经常会用到一些js技巧"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开发中经常会用到一些js技巧</span></span></h2><div class="notion-text notion-block-6c4a20823deb494dbdea3dd50a2409ae">收录如下</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-9602ddc2d48e4606ad8d9ed0ca322bc3" data-id="9602ddc2d48e4606ad8d9ed0ca322bc3"><span><div id="9602ddc2d48e4606ad8d9ed0ca322bc3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9602ddc2d48e4606ad8d9ed0ca322bc3" title="1.数据判空"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.数据判空</span></span></h3><div class="notion-text notion-block-41a550588455427991d2ac1e1e39bb32">支持传入任何常见数据，判断他是否有值</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d85c3a9c0b79405586b8d027ab728245" data-id="d85c3a9c0b79405586b8d027ab728245"><span><div id="d85c3a9c0b79405586b8d027ab728245" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d85c3a9c0b79405586b8d027ab728245" title="2.利用 reduce 进行数据结构的转换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.<b>利用 reduce 进行数据结构的转换</b></span></span></h3><div class="notion-text notion-block-a9c81ac1532348c491ebc955a014660c"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">reduce用法</a></div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-c38da47fbd5c4564a10e9e15ffe58dad" data-id="c38da47fbd5c4564a10e9e15ffe58dad"><span><div id="c38da47fbd5c4564a10e9e15ffe58dad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c38da47fbd5c4564a10e9e15ffe58dad" title="3.函数只执行一次"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.<b>函数只执行一次</b></span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-7d11cb212ee64e4092b83edb5daebe1f" data-id="7d11cb212ee64e4092b83edb5daebe1f"><span><div id="7d11cb212ee64e4092b83edb5daebe1f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7d11cb212ee64e4092b83edb5daebe1f" title="4.实现单例模式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.实现单例模式</span></span></h3><div class="notion-text notion-block-21ac4fa6fcf5458f872187d6f1b17cc8">avaScript 的单例模式是一种常用的设计模式，它可以确保一个类只有一个实例，并提供对该实例的全局访问点，在 JS 中有广泛的应用场景，如购物车，缓存对象，全局的状态管理等等。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-98084e9ee6a6426e9e24a0c4b7bf974e" data-id="98084e9ee6a6426e9e24a0c4b7bf974e"><span><div id="98084e9ee6a6426e9e24a0c4b7bf974e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#98084e9ee6a6426e9e24a0c4b7bf974e" title="5.实现commonJs规范"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.实现commonJs规范</span></span></h3><div class="notion-text notion-block-bde6ac92ff86440186e8c83a5e06fa2e">CommonJS 规范的核心思想是将每个文件都看作一个模块，每个模块都有自己的作用域，其中的变量、函数和对象都是私有的，不能被外部访问。要访问模块中的数据，必须通过导出（exports）和导入（require）的方式。</div><div class="notion-blank notion-block-531e7bd6db734a959957bd18706aa5cc"> </div><div class="notion-blank notion-block-ecc348b760d6469d87f7ac6683f3d38b"> </div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-c6f339c62c524075ba796adeed354429" data-id="c6f339c62c524075ba796adeed354429"><span><div id="c6f339c62c524075ba796adeed354429" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c6f339c62c524075ba796adeed354429" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h4><ul class="notion-list notion-list-disc notion-block-24d17ba9ed0a4598a86ffbc86f4ee6d7"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://juejin.cn/post/7223938976158957624">https://juejin.cn/post/7223938976158957624</a></li></ul><div class="notion-blank notion-block-c638bb49bee740d7aede0a1fd417b163"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>