猫大叔
关注前端,热爱生活
2024-03-17T14:11:55.807Z
http://21ido.com/
猫大叔
Hexo
深入理解node.js模块
http://21ido.com/2024/03/69025b32/
2024-03-09T15:19:56.000Z
2024-03-17T14:11:55.807Z
<p>未完,更新中</p>
<p>JavaScript的思想是一切皆对象,而Node.js编程是基于模块化思想的。</p>
<h3 id="1-基本概念"><a href="#1-基本概念" class="headerlink" title="1. 基本概念"></a>1.
npm、yarn和pnpm的古往今来
http://21ido.com/2023/12/4fefd04c/
2023-12-14T13:36:52.000Z
2024-03-17T14:11:55.807Z
<h3 id="I-引言"><a href="#I-引言" class="headerlink" title="I. 引言"></a>I. 引言</h3><p>本文将深入探讨这三种包管理工具的背景、特点和使用场景,以帮助读者更好地了解它们,为自己的项目选择合适的工具。从最初的 Node.js 发布到包管理工具的崛起和不断演进,我们将带您一一解读,探索它们背后的故事和技术细节。</p>
<p>无论您是新手开发者还是资深工程师,相信本文都能为您带来一些有价值的信息和启发。让我们一起探索 npm、Yarn 和 PNPM 的世界,为我们的项目选择最佳伙伴!</p>
<h4 id="1-npm背景介绍"><a href="#1-npm背景介绍" class="headerlink" title="1. npm背景介绍"></a>1. npm背景介绍</h4><p>Node.js的第一个版本是由Ryan Dahl创建的,最初发布于2009年5月27日<br>该版本基于v8引擎,提供了一个事件驱动、非阻塞I/O环境,使得JS可以运行在服务器环境下<br>而为了解决node.js生态系统中包的管理问题,在2010年,Isaac Z. Schlueter发布了npm</p>
<h4 id="2-包管理工具的重要性"><a href="#2-包管理工具的重要性" class="headerlink" title="2. 包管理工具的重要性"></a>2. 包管理工具的重要性</h4><p>包管理工具在现代软件开发中是不可或缺的一部分,其重要性体现在以下几个方面:</p>
<ol>
<li><strong>依赖管理</strong><br>软件开发通常依赖于许多第三方库和工具。包管理工具能够方便地安装、更新和卸载这些依赖,确保项目能够顺利运行并保持最新状态。</li>
<li><strong>版本控制</strong><br>包管理工具提供了对依赖项版本的控制机制。通过语义化版本控制(Semantic Versioning),开发者能够明确指定项目对依赖项的版本要求,避免由于版本不一致导致的兼容性问题。</li>
<li><strong>易于分享和分发</strong><br>包管理工具使得开发者能够方便地分享自己的代码库(包)给其他人使用。这种分享机制促进了开源社区的发展,使得开发者能够从全球范围内获取并贡献代码。</li>
<li><strong>构建和部署</strong><br>包管理工具通常集成了构建和打包的功能,简化了项目的构建过程。通过包管理工具,开发者可以轻松地将项目部署到生产环境中。</li>
<li><strong>自动化任务</strong><br>包管理工具支持定义和运行各种自动化任务,例如运行测试、执行代码风格检查、生成文档等。这些任务可以通过配置文件或命令行参数进行定制,提高了开发过程的效率。</li>
<li><strong>安全性</strong><br>包管理工具通常包含安全审查机制,能够检测并报告依赖项中存在的安全漏洞。这有助于开发者及时采取措施,保障项目的安全性。</li>
<li><strong>多项目管理</strong><br>对于大型项目或使用多个子项目的情况,包管理工具支持工作区(workspace)和多包存储库,使得依赖项的管理更加灵活。</li>
<li><strong>环境隔离</strong><br>包管理工具可以创建虚拟环境,将项目的依赖项隔离开来,避免了不同项目之间的冲突。这种隔离有助于确保项目在不同环境中的稳定性。</li>
</ol>
当空数组遇上every, some
http://21ido.com/2023/09/1a355503/
2023-09-16T02:18:12.000Z
2024-03-17T14:11:55.807Z
<p>早在17年写过一篇JS数组的文章<br><a href="/2017/03/10afd6ef/" title="Javascript数组的every、some、map、filter、forEach">Javascript数组的every、some、map、filter、forEach</a></p>
<p>文中提到</p>
<blockquote>
<p><em>every</em>,判断是否所有元素都符合,需要每个都为true才返回true,否则返回false</p>
</blockquote>
<p>这个说法有误,当传入空数组时,返回的也是 true</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[].<span class="title function_">every</span>(<span class="function"><span class="params">_</span> =></span> <span class="literal">true</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//--> true</span></span><br></pre></td></tr></table></figure>
<p>所以并不是说数组每个都为true时结果才为true,这点就很费解了<br>然后搜了ECMA-262规范的实现<br>
EventSource使用指南
http://21ido.com/2023/07/b5cab5bb/
2023-07-27T03:46:25.000Z
2024-03-17T14:11:55.803Z
<p>EventSource是基于http协议的推送技术,用于服务器主动向客户端发送数据,而不需要客服端主动请求</p>
<h3 id="1-优缺点"><a href="#1-优缺点" class="headerlink" title="1. 优缺点"></a>1. 优缺点</h3><p>优点:</p>
<ol>
<li>基于http1.1,目前浏览器都支持</li>
<li>自动断线重连,无需另写心跳检测</li>
<li>支持自定义消息类型</li>
</ol>
<p>缺点:</p>
<ol>
<li>单向通讯,客户端无法向服务端发送数据</li>
<li>仅支持纯文本,二进制数据需转码才能传送</li>
</ol>
<p>相比于Websocket,EventSource更加轻量级,而且Websocket是独立协议,需要服务端支持<br>除了不能主动发送数据,可以说Websocket能做的,EventSource都能做</p>
<h3 id="2-应用场景"><a href="#2-应用场景" class="headerlink" title="2. 应用场景"></a>2. 应用场景</h3><ul>
<li>ChatGPT</li>
<li>天气预报</li>
<li>股票外汇等价格牌</li>
<li>火车公交位置牌</li>
</ul>
<h3 id="3-建立连接"><a href="#3-建立连接" class="headerlink" title="3. 建立连接"></a>3. 建立连接</h3><p><img src="/images/2023/07/eventsource1.png" alt="EventSource"></p>
<p>EventSource使用简单,目前流行浏览器均支持</p>
<p>本文用node来写服务端的请求response<br>
什么是灰度测试
http://21ido.com/2023/05/434fdf21/
2023-05-22T03:03:27.000Z
2024-03-17T14:11:55.807Z
<h2 id="1-灰度的来源"><a href="#1-灰度的来源" class="headerlink" title="1. 灰度的来源"></a>1. 灰度的来源</h2><p>当软件升级迭代在遇到架构或功能大改动(技术层面),或是需求和操作的大调整(用户体验层面),往往不是全量发布,而是先小范围发布,没有问题再增量到全部用户,这一过程,类似由白到黑的过度,而白与黑之间均为灰色,所以这一部署过程也叫灰度测试</p>
<h2 id="2-目的"><a href="#2-目的" class="headerlink" title="2. 目的"></a>2. 目的</h2><p>灰度测试是软件发布的一种测试方法,它通过向一小部分真实用户开放测试,接收他们的真实使用反馈和及时修复问题,从而降低改动带来的风险。</p>
<h2 id="3-流程"><a href="#3-流程" class="headerlink" title="3. 流程"></a>3. 流程</h2><p>灰度测试的流程可以概括为以下几个步骤:</p>
<ol>
<li>确定测试目标和测试人员:在灰度测试前,需要明确测试的目标和测试人员,以便确定测试的范围和测试指标。</li>
<li>确定策略:包括部署策略、用户规模、覆盖率和回滚策略。</li>
<li>分批次放量:需要分批次放量,先将新版本软件部署给一部分用户使用,观察其运行情况。如果没有问题,再逐渐扩大用户量,直至将新版本软件全部部署。</li>
<li>收集反馈和修复问题:在测试过程中,需要及时收集用户的反馈和问题,对问题进行分析和修复</li>
<li>再次发布新版本,确保没问题后逐渐扩大用户覆盖范围,直到100%全覆盖</li>
</ol>
<h2 id="4-注意事项"><a href="#4-注意事项" class="headerlink" title="4. 注意事项"></a>4. 注意事项</h2><ol>
<li>在真实环境下进行灰度测试,尽可能模拟真实的用户使用场景。</li>
<li>分析测试结果,并及时修复问题。</li>
<li>有一个完善的测试计划和测试指标,以便于评估测试的效果。</li>
</ol>
<p>综上所述,灰度测试是软件开发过程中不可或缺的环节,可以帮助开发人员及时发现和修复问题,提高软件的质量和用户体验。但是,在进行灰度测试时需要注意相关的注意事项,以确保测试的有效性和可靠性</p>
<h2 id="5-部署"><a href="#5-部署" class="headerlink" title="5. 部署"></a>5. 部署</h2><p>本章图片均搜自谷歌,如有冒犯,请联系我删除</p>
<h3 id="5-1-蓝绿部署"><a href="#5-1-蓝绿部署" class="headerlink" title="5.1 蓝绿部署"></a>5.1 蓝绿部署</h3><p><img src="/images/2023/05/grey1.png" alt="蓝绿部署" title="蓝绿部署"></p>
<p>蓝色为原始版本环境,绿色为新版本环境<br>
Github Actions实现Hexo自动化部署
http://21ido.com/2023/05/49292e5e/
2023-05-03T15:26:22.000Z
2024-03-17T14:11:55.803Z
<p>本文介绍了如何使用GitHub Actions实现Hexo自动化部署,并指出了一些现有YAML代码所引用的脚本比较老导致报错的问题。</p>
<p>Hexo是一个快速、简单且强大的静态博客框架,而GitHub Actions则是一项功能强大的CI/CD工具,可以自动化地执行软件开发工作流程,用于自动构建、测试和部署代码,从而加快软件开发周期。</p>
<p>GitHub Actions使用YAML脚本语言,一种轻量级的标记语言,语法简单,相比JSON更加简介,可以轻松地编写和维护自动化工作流程。</p>
<h2 id="1-SSH秘钥"><a href="#1-SSH秘钥" class="headerlink" title="1. SSH秘钥"></a>1. SSH秘钥</h2><p>我的Hexo分2个Git仓库,源码为私库 21ido.com,发布到 GitHub Pages为公开库 think2cat.github.io</p>
<p>因为是从源码私库push到Pages公开库,此时需要在公开库设置公钥</p>
<h3 id="1-1-生成秘钥"><a href="#1-1-生成秘钥" class="headerlink" title="1.1 生成秘钥"></a>1.1 生成秘钥</h3><p>执行下面代码,其中邮箱替换成自己的<br><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa -b <span class="number">4096</span> -C "gavin2026@xxx.com" -f hexo -N ""</span><br></pre></td></tr></table></figure></p>
<p>生成2个文件,hexo 和 hexo.pub</p>
<h3 id="1-2-设置公钥"><a href="#1-2-设置公钥" class="headerlink" title="1.2 设置公钥"></a>1.2 设置公钥</h3><p>用记事本打开 hexo.pub,全选复制后到GitHub Pages库</p>
<p>Settings > Deploy keys > Add deploy key</p>
<p><img src="/images/2023/05/actions1.png" alt="Deploy key"><br>
宏任务、微任务
http://21ido.com/2020/09/5bd537b/
2020-09-14T02:34:10.000Z
2024-03-17T14:11:55.807Z
<p>首先,JavaScript是单线程语言</p>
<h3 id="1-进程和线程的关系"><a href="#1-进程和线程的关系" class="headerlink" title="1. 进程和线程的关系"></a>1. 进程和线程的关系</h3><p>一个程序至少有一个进程,而一个进程至少有一个线程<br>线程是进程的实体,是CPU调度和分派的基本单位,可以看成实际在干活运算的是线程,而进程只是一个或多个线程的资源分配和调度的系统单位</p>
<p>进程如果是一个工厂,线程则是工厂里干活的工人<br>工人共享一个劳动空间,共享劳动工具</p>
<p>就是说进程里,有一个或多个线程,各线程共享同个内存空间和数据</p>
<p>可以看看阮一峰的<a href="https://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html">《进程与线程的一个简单解释》</a></p>
<h3 id="2-浏览器是多线程"><a href="#2-浏览器是多线程" class="headerlink" title="2. 浏览器是多线程"></a>2. 浏览器是多线程</h3><ul>
<li>GUI渲染线程</li>
<li>JS引擎线程</li>
<li>事件触发线程</li>
<li>定时触发线程</li>
<li>异步http请求线程</li>
</ul>
<p>其中,GUI线程和JS线程,是互斥!也就是某些页面在做JS运算时,会导致DOM刷新卡住的根源。<br>所以当JS线程在执行运算时,GUI线程是挂起的<br>早期通过在代码增加<code>setTimeout</code>来解决渲染卡顿问题</p>
<h3 id="3-Javascript是单线程"><a href="#3-Javascript是单线程" class="headerlink" title="3. Javascript是单线程"></a>3. Javascript是单线程</h3><p>JavaScript可以同时执行多个JS文件代码,看似多线程同时执行,其实还是单线程,只不过是分隔成多个任务,在不同任务跳转进行运算</p>
<p>Javascript的执行机制称为Event Loop</p>
<p>任务又分为同步和异步</p>
<p>同步任务都在主线程上执行,遇到异步任务,则丢到任务队列,接着继续执行同步任务,等到同步任务执行完毕,主线程空闲了,才会回过头去查看任务队列</p>
<p><img src="/images/2020/09/task.jpg" alt="event loop"><br>(图片搜自谷歌)<br>
VUE代码规范
http://21ido.com/2019/07/c9ca51c5/
2019-07-22T06:21:08.000Z
2024-03-17T14:11:55.803Z
<p>为规范代码特写了本文,但实际由于历史包袱,还有很多jQuery时代的代码,加上人员技术水平不齐,执行起来非常有难度</p>
<h2 id="1-目的"><a href="#1-目的" class="headerlink" title="1. 目的"></a>1. 目的</h2><ol>
<li>易于阅读和理解</li>
<li>有助于debug</li>
<li>方便接手的人</li>
<li>不挖坑</li>
</ol>
<h2 id="2-目录和文件规范"><a href="#2-目录和文件规范" class="headerlink" title="2. 目录和文件规范"></a>2. 目录和文件规范</h2><h3 id="2-1-目录结构"><a href="#2-1-目录结构" class="headerlink" title="2.1 目录结构"></a>2.1 目录结构</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">src 源码目录</span><br><span class="line">|-- api 接口,统一管理</span><br><span class="line">|-- assets 静态资源,统一管理</span><br><span class="line">|-- components 公用组件,全局文件</span><br><span class="line">|-- config 配置信息</span><br><span class="line">|-- filters 过滤器,全局工具</span><br><span class="line">|-- icons 图标,全局资源</span><br><span class="line">|-- layout 页面模板</span><br><span class="line">|-- libs 公用工具库</span><br><span class="line">|-- mock 模拟接口,临时存放</span><br><span class="line">|-- store vuex, 状态管理</span><br><span class="line">|-- router 路由,统一管理</span><br><span class="line">|-- views 视图目录</span><br><span class="line">| |-- account 视图模块名</span><br><span class="line">| |-- |-- mygroup.vue 模块入口页面</span><br></pre></td></tr></table></figure>
ES6笔记(3)类
http://21ido.com/2019/03/1eabff52/
2019-03-01T10:04:38.000Z
2024-03-17T14:11:55.803Z
<p>ES5是没有类这个东西,虽然可以写出看起来像类的代码</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Cat</span> (name, color) {</span><br><span class="line"> <span class="keyword">let</span> ret = <span class="title class_">Object</span>.<span class="title function_">create</span>(<span class="title class_">Cat</span>.<span class="property"><span class="keyword">prototype</span></span>)</span><br><span class="line"> ret.<span class="property">name</span> = name</span><br><span class="line"> ret.<span class="property">color</span> = color</span><br><span class="line"> <span class="keyword">return</span> ret</span><br><span class="line">}</span><br><span class="line"><span class="title class_">Cat</span>.<span class="property"><span class="keyword">prototype</span></span> = {</span><br><span class="line"> <span class="attr">say</span>: <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'say'</span>, <span class="variable language_">this</span>.<span class="property">name</span>)</span><br><span class="line"> },</span><br><span class="line"> <span class="attr">eat</span>: <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'eat'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用</span></span><br><span class="line"><span class="keyword">let</span> <span class="title class_">BlackCat</span> = <span class="title class_">Cat</span>(<span class="string">'Lily'</span>, <span class="number">1</span>)</span><br><span class="line"><span class="title class_">BlackCat</span>.<span class="title function_">say</span>()</span><br><span class="line"><span class="comment">// => say lily</span></span><br></pre></td></tr></table></figure>
<p>到了ES6,有了比较正经的写法<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Cat</span> {</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">name, color</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">name</span> = name</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">color</span> = color</span><br><span class="line"> }</span><br><span class="line"> <span class="title function_">say</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'say'</span>, <span class="variable language_">this</span>.<span class="property">name</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="title function_">eat</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'eat'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用</span></span><br><span class="line"><span class="keyword">let</span> <span class="title class_">BlackCat</span> = <span class="keyword">new</span> <span class="title class_">Cat</span>(<span class="string">'Lily'</span>,<span class="string">'black'</span>)</span><br><span class="line"><span class="title class_">BlackCat</span>.<span class="title function_">say</span>()</span><br><span class="line"><span class="comment">// => say lily</span></span><br></pre></td></tr></table></figure></p>
<p>因为有了构造函数 <code>constructor</code> 看起来就比较像传统类</p>
Canvas踩坑(2)马克笔效果
http://21ido.com/2018/12/27f27d32/
2018-12-24T11:52:27.000Z
2024-03-17T14:11:55.803Z
<p><img src="/images/2018/12/markerpen0.png" alt="Marker Pen"></p>
<p>画笔里面,马克笔算是比较简单,比较难的是铅笔和毛笔</p>
<p>一般的线是由点连起来的,设置好 <code>lineCap</code> 和 <code>lineJoin</code> 即可,但马克笔是由<strong>块</strong>连起来的</p>
<p>当我们拿到一个XY坐标点后,需进行扩大,使其变成一个矩形<br>
Canvas踩坑(1)实时绘制透明线
http://21ido.com/2018/11/4d59cb14/
2018-11-23T08:51:24.000Z
2024-03-17T14:11:55.803Z
<p><img src="/images/2018/11/canvasOpacity_1.png" alt="canvasOpacity_1"></p>
<p>Canvas画线算是最基础的操作,涉及的方法也比较简单</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">_cv = _canvas.<span class="title function_">getContext</span>(<span class="string">'2d'</span>);</span><br><span class="line">_cv.<span class="property">lineWidth</span> = <span class="number">20</span></span><br><span class="line">_cv.<span class="property">strokeStyle</span> = <span class="string">'red'</span></span><br><span class="line">_cv.<span class="title function_">beginPath</span>()</span><br><span class="line">_cv.<span class="title function_">moveTo</span>(point.<span class="property">x</span>, point.<span class="property">y</span>)</span><br><span class="line">_cv.<span class="title function_">lineTo</span>(<span class="keyword">new</span>.<span class="property">x</span>, <span class="keyword">new</span>.<span class="property">y</span>)</span><br><span class="line">_cv.<span class="title function_">stroke</span>()</span><br></pre></td></tr></table></figure>
<p>点很多的话,加个 <code>for</code> 循环也轻松搞定,如果画的是透明线,只需用 RGBA 格式即可,比如上图颜色为<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">_cv.<span class="property">strokeStyle</span> = <span class="string">'rgba(253, 150, 38, 0.41)'</span></span><br></pre></td></tr></table></figure><br>
element-ui upload组件覆写默认上传行为
http://21ido.com/2018/09/a91bebb6/
2018-09-20T03:15:35.000Z
2024-03-17T14:11:55.807Z
<p>element-ui 自带了上传组件,支持多文件,支持文件列表显示,支持定义各种钩子,非常方便</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">el-upload</span></span></span><br><span class="line"><span class="tag"> <span class="attr">ref</span>=<span class="string">"upload"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:show-file-list</span>=<span class="string">"false"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:action</span>=<span class="string">"uploadUrl"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:before-upload</span>=<span class="string">"handleBeforeUpload"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:on-progress</span>=<span class="string">"handleUploading"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:on-success</span>=<span class="string">"handleUpload"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:on-error</span>=<span class="string">"handleUploadError"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">accept</span>=<span class="string">".apk"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:auto-upload</span>=<span class="string">"true"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">slot</span>=<span class="string">"trigger"</span> <span class="attr">:loading</span>=<span class="string">"uploadLoading"</span> <span class="attr">size</span>=<span class="string">"mini"</span> <span class="attr">type</span>=<span class="string">"primary"</span>></span>上传<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">v-html</span>=<span class="string">"tips"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">el-upload</span>></span></span><br></pre></td></tr></table></figure>
<p>同时也提供了 <code>http-request</code> 参数来自定义上传行为<br>
异步回调之generator(1)入门篇
http://21ido.com/2018/09/ddbd4da6/
2018-09-11T09:39:39.000Z
2024-03-17T14:11:55.807Z
<h3 id="什么是Generator"><a href="#什么是Generator" class="headerlink" title="什么是Generator"></a>什么是Generator</h3><p>Generator 是ES6新特性,是另一种异步编程解决方案,提供了与之前传统函数不一样的语法行为<br>如果说Promise解决了回调函数的地狱式嵌套,Generator则解决了Promise.then()的多级链式调用</p>
<h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><p><code>function* Generator()</code> Generator写法跟普通函数一样,<code>function</code> 和函数名 <code>Generator</code> 中间多了个<code>*</code>号,同时函数内部可以使用 <code>yield</code> 进行暂停并输出值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// *号可随意放置,推荐使用第一种写法</span></span><br><span class="line"><span class="keyword">function</span>* <span class="title class_">Generator</span>() {}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> * <span class="title class_">Generator</span>() {}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> *<span class="title class_">Generator</span>() {}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span>*<span class="title class_">Generator</span>() {}</span><br></pre></td></tr></table></figure>
Axios笔记(2)
http://21ido.com/2018/08/786557a3/
2018-08-31T09:11:44.000Z
2024-03-17T14:11:55.807Z
<h2 id="实例化"><a href="#实例化" class="headerlink" title="实例化"></a>实例化</h2><p>上一篇说了基本用法,实际使用中并不会直接调用,而是实例化一个对象<br>并配置好基本参数,然后所有请求走实例化对象<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> service = axios.<span class="title function_">create</span>({</span><br><span class="line"> <span class="attr">baseURL</span>: <span class="string">'/api1.0/'</span></span><br><span class="line"> <span class="attr">timeout</span>: <span class="number">5000</span> <span class="comment">// request timeout</span></span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">list</span>(<span class="params">query</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">service</span>({</span><br><span class="line"> <span class="attr">url</span>: <span class="string">'getList'</span>,</span><br><span class="line"> <span class="attr">method</span>: <span class="string">'post'</span>,</span><br><span class="line"> <span class="attr">data</span>: query</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 调用示例</span></span><br><span class="line"><span class="title function_">list</span>(query).<span class="title function_">then</span>()</span><br></pre></td></tr></table></figure><br>配置参数较多,参照 <a href="https://github.com/axios/axios">Axios官网</a></p>
<h2 id="拦截器"><a href="#拦截器" class="headerlink" title="拦截器"></a>拦截器</h2><p>axios支持拦截器,可以在请求和返回时进行拦截处理
Axios笔记(1)
http://21ido.com/2018/08/e16c0619/
2018-08-24T05:02:03.000Z
2024-03-17T14:11:55.807Z
<p>Axios 是基于 promise 的http库,可在nodejs服务端或客户端浏览器运行<br>其中浏览器使用XMLHttpRequests对象进行请求<br><a href="https://github.com/axios/axios/">Github地址</a></p>
<h2 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h2><ol>
<li>支持服务端和客户端</li>
<li>基于Promise</li>
<li>支持请求和响应拦截</li>
<li>支持JSON格式转换</li>
<li>支持取消请求
Promise入门指南(5)
http://21ido.com/2018/08/33ad2a19/
2018-08-09T16:26:24.000Z
2024-03-17T14:11:55.803Z
<h3 id="Promise-catch"><a href="#Promise-catch" class="headerlink" title="Promise.catch"></a>Promise.catch</h3><p><code>catch</code> 是用来捕获异常的,但是网上很多教程代码把 <code>catch</code> 当 <code>rejected</code> 使用,这是不当的</p>
<p>前面说了 Promise 有3种状态, pending, fulffilled, rejected<br>并没有一种状态叫异常,实际使用中,能确定的状态用 resolve / reject 来回调,而不是丢到 catch</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 错误示例</span></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="comment">// try something</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">'something error'</span>)</span><br><span class="line">})</span><br><span class="line">p1.<span class="title function_">then</span>(<span class="function"><span class="params">v</span> =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'p2'</span>, v)</span><br><span class="line">}).<span class="title function_">catch</span>(<span class="function"><span class="params">v</span> =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'p3'</span>, v)</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<p>这样当报错时,会抛到 catch 去执行,而实际有些错误是可预见的,所以当可预见和不可预见的错误,都往 catch 报的时候,就没法判断了,因此建议用 reject 来处理可预见性的错误<br>
Promise入门指南(4)
http://21ido.com/2018/07/2ab61b58/
2018-07-21T15:25:12.000Z
2024-03-17T14:11:55.803Z
<h3 id="Promise-all"><a href="#Promise-all" class="headerlink" title="Promise.all"></a>Promise.all</h3><p>有一些场景,需要同时调用几个接口,拿到全部返回数据,才能接着往下调用<br>以往遇到这种情况,需要设置一些临时变量来记录每个接口是否返回数据,每次返回时再判断是否数据已经齐全,再往下接着走<br>而 all 方法就是为此而生的,接受参数为 Promise对象数组<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> pArr = [];</span><br><span class="line">pArr.<span class="title function_">push</span>(<span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"p1 resolve"</span>);</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="string">"resp1"</span>);</span><br><span class="line"> }, <span class="number">1000</span>);</span><br><span class="line">}))</span><br><span class="line">pArr.<span class="title function_">push</span>(<span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"p2 resolve"</span>);</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="string">"resp2"</span>);</span><br><span class="line"> }, <span class="number">5000</span>);</span><br><span class="line">}));</span><br><span class="line">pArr.<span class="title function_">push</span>(<span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"p3 resolve"</span>);</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="string">"resp3"</span>);</span><br><span class="line"> }, <span class="number">3000</span>);</span><br><span class="line">}));</span><br><span class="line"><span class="keyword">let</span> p = <span class="title class_">Promise</span>.<span class="title function_">all</span>(pArr);</span><br><span class="line">p.<span class="title function_">then</span>(<span class="function"><span class="params">resp</span> =></span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"all is done, doing next"</span>);</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">// => p1 resolve</span></span><br><span class="line"><span class="comment">// => p3 resolve</span></span><br><span class="line"><span class="comment">// => p2 resolve</span></span><br><span class="line"><span class="comment">// => all is done, doing next</span></span><br></pre></td></tr></table></figure><br>
Promise入门指南(3)
http://21ido.com/2018/07/65f78d9f/
2018-07-15T10:44:55.000Z
2024-03-17T14:11:55.803Z
<p>Promise是JavaScript异步编程解决方案,之一<br>以往我们所习惯的回调函数也是之一,还有事件监听和观察者模式(也叫发布订阅模式)也算<br>而Promise是遵循的是Promise/A+规范,像Axios也是遵循这个规范,提供了相同的api</p>
<p>Promise/A+规范解决了回调函数的一些弊端,比如</p>
<ul>
<li>代码书写逻辑</li>
<li>更改回调顺序的噩梦</li>
<li>多步回调的魔鬼嵌套</li>
<li>回调函数的跟踪</li>
</ul>
<p>但Promise也不是万能的,作为解决方案之一,并不是适合所有的异步场景</p>
<p>前面说到Promise特征之一就是状态一旦变成 fulfilled 或是 rejected ,则不会再改变,而当执行 then 进行 resolve 和 rejected 回调注册时,返回的其实是一个新的Promise对象</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="built_in">setTimeout</span>( <span class="function">() =></span> {</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">getTime</span>());</span><br><span class="line"> },<span class="number">1000</span>);</span><br><span class="line">});</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">dir</span>(p);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">dir</span>(p.<span class="title function_">then</span>(<span class="function">(<span class="params">v</span>) =></span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">getTime</span>();</span><br><span class="line">}));</span><br></pre></td></tr></table></figure>
Promise入门指南(2)
http://21ido.com/2018/07/7cecbcde/
2018-07-13T10:01:16.000Z
2024-03-17T14:11:55.803Z
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="keyword">function</span>(<span class="params">resolve, reject</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="keyword">function</span>(<span class="params"></span>){</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'finished'</span>);</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="string">'someone'</span>);</span><br><span class="line"> }, <span class="number">2000</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>前面提到的这种写法,实际不会这么直接把Promise赋值给p,因为大部分function调用需要传入参数,所以习惯在function里面 <code>new Promise</code> 示例并return<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="title function_">getUrl</span> = param => {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> $.<span class="title function_">ajax</span>(url, <span class="function"><span class="params">response</span> =></span> {</span><br><span class="line"> <span class="title function_">resolve</span>(response);</span><br><span class="line"> });</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line"><span class="title function_">getUrl</span>(<span class="number">1</span>).<span class="title function_">then</span>(<span class="function"><span class="params">response</span> =></span> {</span><br><span class="line"> <span class="title function_">render</span>(response);</span><br><span class="line">});</span><br></pre></td></tr></table></figure><br>这是比较标准的写法,还有比较偷懒的写法<br>
Promise入门指南(1)
http://21ido.com/2018/06/57c1ef1d/
2018-06-04T06:48:28.000Z
2024-03-17T14:11:55.803Z
<h3 id="Promise是异步编程的解决方案"><a href="#Promise是异步编程的解决方案" class="headerlink" title="Promise是异步编程的解决方案"></a>Promise是异步编程的解决方案</h3><p>Promise有3种状态</p>
<ul>
<li>pending</li>
<li>fulfilled</li>
<li>rejected</li>
</ul>
<p>对象的状态是不受外界影响的,而且状态的改变只有两种</p>
<ol>
<li>pending -> fulfilled</li>
<li>pending -> rejected</li>
</ol>
<p>一旦变成fulfilled或rejected,则终止,不会再改变<br>而在pending阶段,是不能取消,即一旦开始执行,就只能等状态改变,无法中途取消操作</p>
<h3 id="代码示例"><a href="#代码示例" class="headerlink" title="代码示例"></a>代码示例</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="keyword">function</span>(<span class="params">resolve, reject</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="keyword">function</span>(<span class="params"></span>){</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'finished'</span>);</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="string">'someone'</span>);</span><br><span class="line"> }, <span class="number">2000</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>