-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLearn-Promise.html
1 lines (1 loc) · 54.7 KB
/
Learn-Promise.html
1
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=2"><meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.4.0"><link rel="apple-touch-icon" sizes="180x180" href="/images/favicon-32x32.png"><link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png"><link rel="mask-icon" href="/images/favicon-32x32.png" color="#222"><link rel="stylesheet" href="/css/main.css"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/all.min.css" integrity="sha256-2H3fkXt6FEmrReK448mDVGKb3WW2ZZw35gI7vqHOE4Y=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/[email protected]/dist/jquery.fancybox.min.css" integrity="sha256-Vzbj7sDDS/woiFS3uNKo8eIuni59rjyNGtXfstRzStA=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/nprogress.css" integrity="sha256-no0c5ccDODBwp+9hSmV5VvPpKwHCpbVzXHexIkupM6U=" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/[email protected]/nprogress.js" integrity="sha256-a5YRB27CcBwBFcT5EF/f3E4vzIqyHrSR878nseNYw64=" crossorigin="anonymous"></script><script class="next-config" data-name="main" type="application/json">{"hostname":"www.wrysmile.cn","root":"/","images":"/images","scheme":"Gemini","version":"8.5.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":true,"bookmark":{"enable":true,"color":"#222","save":"manual"},"fancybox":true,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果:${query}","hits_time":"找到 ${hits} 个搜索结果(用时 ${time} 毫秒)","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script><meta name="description" content="介绍 本文主要记录在学习尚硅谷的 Promise 课程时的一些笔记 尚硅谷前端学科全套课程请点击这里进行下载,提取码:afyt"><meta property="og:type" content="article"><meta property="og:title" content="学习笔记:Promise(尚硅谷)"><meta property="og:url" content="https://www.wrysmile.cn/Learn-Promise.html"><meta property="og:site_name" content="Wrysmile 的博客"><meta property="og:description" content="介绍 本文主要记录在学习尚硅谷的 Promise 课程时的一些笔记 尚硅谷前端学科全套课程请点击这里进行下载,提取码:afyt"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://z3.ax1x.com/2021/07/15/WnyxeS.png"><meta property="og:image" content="https://z3.ax1x.com/2021/07/19/WJro38.png"><meta property="article:published_time" content="2021-07-15T07:16:34.000Z"><meta property="article:modified_time" content="2023-01-31T10:23:56.195Z"><meta property="article:author" content="Zhang Yangeng"><meta property="article:tag" content="前端"><meta property="article:tag" content="学习"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://z3.ax1x.com/2021/07/15/WnyxeS.png"><link rel="canonical" href="https://www.wrysmile.cn/Learn-Promise.html"><script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://www.wrysmile.cn/Learn-Promise.html","path":"Learn-Promise.html","title":"学习笔记:Promise(尚硅谷)"}</script><script class="next-config" data-name="calendar" type="application/json">""</script><title>学习笔记:Promise(尚硅谷) | Wrysmile 的博客</title><script>!function(e,t,o,c,i,a,n){e.DaoVoiceObject=i,e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},e[i].l=+new Date,a=t.createElement(o),n=t.getElementsByTagName(o)[0],a.async=1,a.src=c,a.charset="utf-8",n.parentNode.insertBefore(a,n)}(window,document,"script",("https:"==document.location.protocol?"https:":"http:")+"//widget.daovoice.io/widget/13e39436.js","daovoice"),daovoice("init",{app_id:"13e39436"}),daovoice("update")</script><noscript><link rel="stylesheet" href="/css/noscript.css"></noscript><link rel="alternate" href="/atom.xml" title="Wrysmile 的博客" type="application/atom+xml"></head><body itemscope itemtype="http://schema.org/WebPage" class="use-motion"><div class="headband"></div><main class="main"><header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="header-inner"><div class="site-brand-container"><div class="site-nav-toggle"><div class="toggle" aria-label="切换导航栏" role="button"><span class="toggle-line"></span> <span class="toggle-line"></span> <span class="toggle-line"></span></div></div><div class="site-meta"><a href="/" class="brand" rel="start"><i class="logo-line"></i><h1 class="site-title">Wrysmile 的博客</h1><i class="logo-line"></i></a><p class="site-subtitle" itemprop="description">欢迎来到我的个人小屋</p><img class="custom-logo-image" src="/images/favicon-32x32.png" alt="Wrysmile 的博客"></div><div class="site-nav-right"><div class="toggle popup-trigger"><i class="fa fa-search fa-fw fa-lg"></i></div></div></div><nav class="site-nav"><ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li><li class="menu-item menu-item-search"><a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索</a></li></ul></nav><div class="search-pop-overlay"><div class="popup search-popup"><div class="search-header"><span class="search-icon"><i class="fa fa-search"></i></span><div class="search-input-container"><input autocomplete="off" autocapitalize="off" maxlength="80" placeholder="搜索..." spellcheck="false" type="search" class="search-input"></div><span class="popup-btn-close" role="button"><i class="fa fa-times-circle"></i></span></div><div class="search-result-container no-result"><div class="search-result-icon"><i class="fa fa-spinner fa-pulse fa-5x"></i></div></div></div></div></div><div class="toggle sidebar-toggle" role="button"><span class="toggle-line"></span> <span class="toggle-line"></span> <span class="toggle-line"></span></div><aside class="sidebar"><div class="sidebar-inner sidebar-nav-active sidebar-toc-active"><ul class="sidebar-nav"><li class="sidebar-nav-toc">文章目录</li><li class="sidebar-nav-overview">站点概览</li></ul><div class="sidebar-panel-container"><div class="post-toc-wrap sidebar-panel"><div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">介绍</span></a></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">一、基础知识</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E5%AE%9E%E4%BE%8B%E5%AF%B9%E8%B1%A1%E4%B8%8E%E5%87%BD%E6%95%B0%E5%AF%B9%E8%B1%A1"><span class="nav-text">1.实例对象与函数对象</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0"><span class="nav-text">2.回调函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-JS%E4%B8%AD%E7%9A%84%E9%94%99%E8%AF%AF"><span class="nav-text">3.JS中的错误</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-%E9%94%99%E8%AF%AF%E7%9A%84%E7%B1%BB%E5%9E%8B"><span class="nav-text">(1).错误的类型</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86"><span class="nav-text">(2).错误处理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-%E9%94%99%E8%AF%AF%E5%AF%B9%E8%B1%A1"><span class="nav-text">(3).错误对象</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">二、Promise</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E7%90%86%E8%A7%A3"><span class="nav-text">1.理解</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E7%8A%B6%E6%80%81"><span class="nav-text">2.状态</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%B5%81%E7%A8%8B"><span class="nav-text">3.流程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E4%BD%BF%E7%94%A8"><span class="nav-text">4.使用</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E4%BC%98%E7%82%B9"><span class="nav-text">5.优点</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%9B%9E%E8%B0%83%E5%9C%B0%E7%8B%B1"><span class="nav-text">!回调地狱</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-API"><span class="nav-text">6.API</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">三、Promise问题</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98Promise%E7%8A%B6%E6%80%81%EF%BC%9F"><span class="nav-text">1.如何改变Promise状态?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E4%B8%80%E4%B8%AAPromise%E6%8C%87%E5%AE%9A%E5%A4%9A%E4%B8%AA%E6%88%90%E5%8A%9F-%E5%A4%B1%E8%B4%A5%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%EF%BC%8C%E9%83%BD%E4%BC%9A%E8%B0%83%E7%94%A8%E5%90%97%EF%BC%9F"><span class="nav-text">2.一个Promise指定多个成功/失败回调函数,都会调用吗?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%94%B9%E5%8F%98Promise%E7%8A%B6%E6%80%81%E5%92%8C%E6%8C%87%E5%AE%9A%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E8%B0%81%E5%85%88%E8%B0%81%E5%90%8E%EF%BC%9F"><span class="nav-text">3.改变Promise状态和指定回调函数谁先谁后?</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-%E5%A6%82%E4%BD%95%E5%85%88%E6%94%B9%E7%8A%B6%E6%80%81%E5%86%8D%E6%8C%87%E5%AE%9A%E5%9B%9E%E8%B0%83%EF%BC%9F"><span class="nav-text">(1).如何先改状态再指定回调?</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E6%89%8D%E8%83%BD%E5%BE%97%E5%88%B0%E6%95%B0%E6%8D%AE%EF%BC%9F"><span class="nav-text">(2).什么时候才能得到数据?</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-then-%E6%96%B9%E6%B3%95%E8%BF%94%E5%9B%9E%E7%9A%84%E6%96%B0promise%E7%9A%84%E7%BB%93%E6%9E%9C%E7%8A%B6%E6%80%81%E7%94%B1%E4%BB%80%E4%B9%88%E5%86%B3%E5%AE%9A%EF%BC%9F"><span class="nav-text">4.then()方法返回的新promise的结果状态由什么决定?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-promise%E5%A6%82%E4%BD%95%E4%B8%B2%E8%81%94%E5%A4%9A%E4%B8%AA%E6%93%8D%E4%BD%9C%E4%BB%BB%E5%8A%A1%EF%BC%9F"><span class="nav-text">5.promise如何串联多个操作任务?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-promise%E5%BC%82%E5%B8%B8%E4%BC%A0-%E7%A9%BF%E9%80%8F%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F"><span class="nav-text">6.promise异常传/穿透是什么?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-%E5%A6%82%E4%BD%95%E4%B8%AD%E6%96%ADpromise%E9%93%BE%EF%BC%9F"><span class="nav-text">7.如何中断promise链?</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">四、自定义Promise</span></a></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">五、async与await</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-async%E5%87%BD%E6%95%B0"><span class="nav-text">1.async函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-await%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="nav-text">2.await表达式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">六、JS异步之两种队列</span></a></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-text">七、面试题</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E9%A2%98%E4%B8%80"><span class="nav-text">1.题一</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E9%A2%98%E4%BA%8C"><span class="nav-text">2.题二</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E9%A2%98%E4%B8%89"><span class="nav-text">3.题三</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E9%A2%98%E5%9B%9B"><span class="nav-text">4.题四</span></a></li></ol></li></ol></div></div><div class="site-overview-wrap sidebar-panel"><div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person"><img class="site-author-image" itemprop="image" alt="Zhang Yangeng" src="/images/avatar.jpg"><p class="site-author-name" itemprop="name">Zhang Yangeng</p><div class="site-description" itemprop="description">保持独立思考,不卑不亢不怂,长成自己想要的样子!</div></div><div class="site-state-wrap site-overview-item animated"><nav class="site-state"><div class="site-state-item site-state-posts"><a href="/archives/"><span class="site-state-item-count">69</span> <span class="site-state-item-name">日志</span></a></div><div class="site-state-item site-state-categories"><a href="/categories/"><span class="site-state-item-count">13</span> <span class="site-state-item-name">分类</span></a></div><div class="site-state-item site-state-tags"><a href="/tags/"><span class="site-state-item-count">52</span> <span class="site-state-item-name">标签</span></a></div></nav></div><div class="links-of-author site-overview-item animated"><span class="links-of-author-item"><a href="https://github.com/zhangyangeng" title="GitHub → https://github.com/zhangyangeng" rel="external nofollow noopener noreferrer" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a> </span><span class="links-of-author-item"><a href="https://weibo.com/u/2294901673" title="weibo → https://weibo.com/u/2294901673" rel="external nofollow noopener noreferrer" target="_blank"><i class="fab fa-weibo fa-fw"></i>weibo</a></span></div><div class="cc-license site-overview-item animated" itemprop="license"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/zh-cn" class="cc-opacity" rel="external nofollow noopener noreferrer" target="_blank"><img src="https://cdn.jsdelivr.net/npm/@creativecommons/[email protected]/assets/license_badges/small/by_nc_sa.svg" alt="Creative Commons"></a></div><div class="links-of-blogroll site-overview-item animated"><div class="links-of-blogroll-title"><i class="fa fa-globe fa-fw"></i> 推荐网站</div><ul class="links-of-blogroll-list"><li class="links-of-blogroll-item"><a href="http://topbook.cc/" title="http://topbook.cc/" rel="external nofollow noopener noreferrer" target="_blank">Topbook</a></li></ul></div></div></div></div></aside><div class="sidebar-dimmer"></div></header><div class="back-to-top" role="button" aria-label="返回顶部"><i class="fa fa-arrow-up"></i> <span>0%</span></div><div class="reading-progress-bar"></div><a role="button" class="book-mark-link book-mark-link-fixed"></a><noscript><div class="noscript-warning">Theme NexT works best with JavaScript enabled</div></noscript><div class="main-inner post posts-expand"><div class="post-block"><article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN"><link itemprop="mainEntityOfPage" href="https://www.wrysmile.cn/Learn-Promise.html"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="image" content="/images/avatar.jpg"><meta itemprop="name" content="Zhang Yangeng"><meta itemprop="description" content="保持独立思考,不卑不亢不怂,长成自己想要的样子!"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="Wrysmile 的博客"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">学习笔记:Promise(尚硅谷)</h1><div class="post-meta-container"><div class="post-meta"><span class="post-meta-item"><span class="post-meta-item-icon"><i class="far fa-calendar"></i> </span><span class="post-meta-item-text">发表于</span> <time title="创建时间:2021-07-15 15:16:34" itemprop="dateCreated datePublished" datetime="2021-07-15T15:16:34+08:00">2021-07-15</time> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="far fa-calendar-check"></i> </span><span class="post-meta-item-text">更新于</span> <time title="修改时间:2023-01-31 18:23:56" itemprop="dateModified" datetime="2023-01-31T18:23:56+08:00">2023-01-31</time> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="far fa-folder"></i> </span><span class="post-meta-item-text">分类于</span> <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" itemprop="url" rel="index"><span itemprop="name">学习笔记</span></a> </span></span><span id="/Learn-Promise.html" class="post-meta-item leancloud_visitors" data-flag-title="学习笔记:Promise(尚硅谷)" title="阅读次数"><span class="post-meta-item-icon"><i class="far fa-eye"></i> </span><span class="post-meta-item-text">阅读次数:</span> <span class="leancloud-visitors-count"></span></span></div><div class="post-meta"><span class="post-meta-item" title="本文字数"><span class="post-meta-item-icon"><i class="far fa-file-word"></i> </span><span class="post-meta-item-text">本文字数:</span> <span>6.5k</span> </span><span class="post-meta-item" title="阅读时长"><span class="post-meta-item-icon"><i class="far fa-clock"></i> </span><span class="post-meta-item-text">阅读时长 ≈</span> <span>6 分钟</span></span></div></div></header><div class="post-body" itemprop="articleBody"><h1>介绍</h1><ul class="lvl-0"><li class="lvl-2">本文主要记录在学习尚硅谷的 Promise 课程时的一些笔记</li><li class="lvl-2">尚硅谷前端学科全套课程请点击<a target="_blank" rel="external nofollow noopener noreferrer" href="https://pan.baidu.com/s/1BM_OKMXXAGxMNqaBN_7tRg">这里</a>进行下载,提取码:afyt<span id="more"></span></li></ul><h1>一、基础知识</h1><h2 id="1-实例对象与函数对象">1.实例对象与函数对象</h2><ul class="lvl-0"><li class="lvl-2"><p>实例对象:new 函数产生的对象,称为实例对象,简称为对象</p></li><li class="lvl-2"><p>函数对象:将函数作为对象使用时,简称为函数对象</p></li></ul><h2 id="2-回调函数">2.回调函数</h2><ul class="lvl-0"><li class="lvl-2"><p>同步回调:</p><ul class="lvl-2"><li class="lvl-4">理解:立即执行,完全执行完了才结束,不会放入回调队列中</li><li class="lvl-4">例子:数组遍历相关的函数、Promise 的 excutor 函数</li></ul></li><li class="lvl-2"><p>异步回调:</p><ul class="lvl-2"><li class="lvl-4">理解:不会立即执行,会放入回调队列中将来执行</li><li class="lvl-4">例子:定时器调用、ajax 回调、Promise 的成功/失败回调</li></ul></li></ul><h2 id="3-JS中的错误">3.JS中的错误</h2><ul class="lvl-0"><li class="lvl-2"><p>具体可看 <a target="_blank" rel="external nofollow noopener noreferrer" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error">MDN</a> 中的解释</p></li></ul><h3 id="1-错误的类型">(1).错误的类型</h3><ul class="lvl-0"><li class="lvl-2"><p><code>Error</code>:所有错误的父类型</p></li><li class="lvl-2"><p><code>ReferenceError</code>:引用错误,引用的变量不存在</p></li><li class="lvl-2"><p><code>TypeError</code>:类型错误,数据类型不正确</p></li><li class="lvl-2"><p><code>RangeError</code>:范围错误,数据值不在其所允许的范围内</p></li><li class="lvl-2"><p><code>SyntaxError</code>:语法错误</p></li></ul><h3 id="2-错误处理">(2).错误处理</h3><ul class="lvl-0"><li class="lvl-2"><p>捕获错误:使用 <code>try...catch</code> 来捕获</p></li></ul><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></pre></td><td class="code"><pre><span class="line">try {</span><br><span class="line"> let a;</span><br><span class="line"> console.log(a.xxx)</span><br><span class="line">} catch (error){</span><br><span class="line"> console.log(error.message);</span><br><span class="line"> console.log(error.stack);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>抛出错误:使用 <code>throw error</code> 来抛出,error 中传一个 message</p></li></ul><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></pre></td><td class="code"><pre><span class="line">function something() {</span><br><span class="line"> if(Date.now() % 2 === 1){</span><br><span class="line"> console.log("当前时间为奇数,可以继续执行");</span><br><span class="line"> } else {</span><br><span class="line"> throw new Error("当前时间为偶数,无法继续执行");</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">try{</span><br><span class="line"> something();</span><br><span class="line">} catch (error) {</span><br><span class="line"> alert(error.message);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-错误对象">(3).错误对象</h3><ul class="lvl-0"><li class="lvl-2"><p>message 属性:错误相关信息</p></li><li class="lvl-2"><p>stack 属性:函数调用栈记录信息</p></li></ul><h1>二、Promise</h1><h2 id="1-理解">1.理解</h2><ul class="lvl-0"><li class="lvl-2"><p>抽象表达:</p><ul class="lvl-2"><li class="lvl-4">Promise 是 JS 中进行异步编程的新方案</li><li class="lvl-4"><strong style="color:red">注意:旧方案为纯回调</strong></li></ul></li><li class="lvl-2"><p>具体表达:</p><ul class="lvl-2"><li class="lvl-4">从语法上来说:Promise 是一个构造函数</li><li class="lvl-4">从功能上来说:Promise 对象用来封装一个异步操作并可以获取其结果</li></ul></li></ul><h2 id="2-状态">2.状态</h2><p>Promise 一共有三种状态:pending、resolved、rejected</p><p>状态改变:</p><ul class="lvl-0"><li class="lvl-3"><p>pending -> resolved,结果数据为 value</p></li><li class="lvl-3"><p>pending -> rejected,结果数据为 reason</p></li></ul><p>一个 Promise 对象只能改变一次,无论变为成功还是失败,都会有一个结果数据</p><h2 id="3-流程">3.流程</h2><ul class="lvl-0"><li class="lvl-2"><p>基本运行流程如下:<br><img src="https://z3.ax1x.com/2021/07/15/WnyxeS.png" alt="promise01.png"></p></li></ul><h2 id="4-使用">4.使用</h2><ul class="lvl-0"><li class="lvl-2"><p>基本使用方法如下:</p></li></ul><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><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></pre></td><td class="code"><pre><span class="line">// 创建一个新的Promise对象</span><br><span class="line">const p = new Promise((resolve, reject) => {// 执行器函数(同步回调)</span><br><span class="line"> // 执行异步操作任务</span><br><span class="line"> setTimeout(() => {</span><br><span class="line"> const time = Date.now();</span><br><span class="line"> if (time % 2 === 0){</span><br><span class="line"> // 成功,调用 resolve</span><br><span class="line"> resolve("当前时间为偶数"+time+"成功");</span><br><span class="line"> }else {</span><br><span class="line"> // 失败,调用 reject</span><br><span class="line"> reject("当前时间为奇数"+time+"失败");</span><br><span class="line"> }</span><br><span class="line"> }, 2000);</span><br><span class="line">});</span><br><span class="line">p.then(</span><br><span class="line"> value => {</span><br><span class="line"> console.log("成功的回调"+value);</span><br><span class="line"> },</span><br><span class="line"> reason => {</span><br><span class="line"> console.log("失败的回调"+reason);</span><br><span class="line"> }</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h2 id="5-优点">5.优点</h2><ul class="lvl-0"><li class="lvl-2"><p>指定回调函数的方式更加灵活:</p><ul class="lvl-2"><li class="lvl-4">旧方法:必须在启动任务前指定</li><li class="lvl-4">Promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)</li></ul></li><li class="lvl-2"><p>支持链式调用,可以解决回调地狱问题</p></li></ul><h3 id="回调地狱">!回调地狱</h3><ul class="lvl-0"><li class="lvl-2"><p>回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件</p></li><li class="lvl-2"><p>缺点:不便于阅读、不便于异常处理</p></li><li class="lvl-2"><p>初级解决方案:promise 链式调用</p></li></ul><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></pre></td><td class="code"><pre><span class="line">doSomething()</span><br><span class="line"> .then(function (result){</span><br><span class="line"> return doSomethingElse(result)</span><br><span class="line"> })</span><br><span class="line"> .then(function (newResult){</span><br><span class="line"> return doThirdThing(newResult)</span><br><span class="line"> })</span><br><span class="line"> .then(function (finalResult){</span><br><span class="line"> console.log("Get the final result" + finalResult)</span><br><span class="line"> })</span><br><span class="line"> .catch(failureCallback)</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>终极解决方案:async / await</p></li></ul><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></pre></td><td class="code"><pre><span class="line">async function request(){</span><br><span class="line"> try{</span><br><span class="line"> const result = await doSomething()</span><br><span class="line"> const newResult = await doSomethingElse(result)</span><br><span class="line"> const finalResult = await doThirdThing(newResult)</span><br><span class="line"> console.log("Get the final result" + finalResult)</span><br><span class="line"> }catch (error){</span><br><span class="line"> failureCallback(error)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="6-API">6.API</h2><ul class="lvl-0"><li class="lvl-2"><p>Promise构造函数:<code>Promise(excutor){}</code></p><ul class="lvl-2"><li class="lvl-4">excutor函数:同步执行 <code>(resolve, reject) => {}</code><ul class="lvl-4"><li class="lvl-6">resolve函数:内部定义成功时我们调用的函数 <code>value => {}</code></li><li class="lvl-6">reject函数:内部定义失败时我们调用的函数 <code>reason => {}</code></li></ul></li><li class="lvl-4">说明:excutor 会在 Promise 内部立即同步回调,异步操作在执行器中执行</li></ul></li><li class="lvl-2"><p>Promise.prototype.then方法:<code>(onResolved, onRejected) => {}</code></p><ul class="lvl-2"><li class="lvl-4">onResolved函数:成功的回调函数 <code>(value) => {}</code></li><li class="lvl-4">onRejeced函数:失败的回调函数 <code>(reason) => {}</code></li><li class="lvl-4">说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调,返回一个新的 promise 对象</li></ul></li><li class="lvl-2"><p>Promise.prototype.catch方法:<code>(onRejectde) => {}</code></p><ul class="lvl-2"><li class="lvl-4">onRejeced函数:失败的回调函数 <code>(reason) => {}</code></li><li class="lvl-4">说明:<code>then()</code> 的语法糖,相当于 <code>then(undefined, onRejected)</code></li></ul></li><li class="lvl-2"><p>Promise.resolve方法:<code>(value) => {}</code></p><ul class="lvl-2"><li class="lvl-4">value:成功的数据或promise对象</li><li class="lvl-4">说明:返回一个成功/失败的promise对象</li></ul></li><li class="lvl-2"><p>Promise.reject方法:<code>(reason) => {}</code></p><ul class="lvl-2"><li class="lvl-4">reason:失败的原因</li><li class="lvl-4">说明:返回一个失败的promise对象</li></ul></li><li class="lvl-2"><p>Promise.all方法:<code>(Promises) => {}</code></p><ul class="lvl-2"><li class="lvl-4">promises:包含n个promise数组</li><li class="lvl-4">说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败就直接失败</li></ul></li><li class="lvl-2"><p>Promise.race方法:<code>(promises) => {}</code></p><ul class="lvl-2"><li class="lvl-4">promises:包含n个promise数组</li><li class="lvl-4">说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态</li></ul></li></ul><h1>三、Promise问题</h1><h2 id="1-如何改变Promise状态?">1.如何改变Promise状态?</h2><ul class="lvl-0"><li class="lvl-2"><p>调用 <code>resolve(value)</code>:如果当前是pending就会变成resolved</p></li><li class="lvl-2"><p>调用 <code>reject(reason)</code>:如果当前是pending就会变成rejected</p></li><li class="lvl-2"><p>抛出异常:如果当前是pending就会变成rejected</p></li></ul><h2 id="2-一个Promise指定多个成功-失败回调函数,都会调用吗?">2.一个Promise指定多个成功/失败回调函数,都会调用吗?</h2><ul class="lvl-0"><li class="lvl-2"><p>当 promise 改变为对应状态时都会调用</p></li></ul><h2 id="3-改变Promise状态和指定回调函数谁先谁后?">3.改变Promise状态和指定回调函数谁先谁后?</h2><ul class="lvl-0"><li class="lvl-2"><p>都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态在指定回调</p></li></ul><h3 id="1-如何先改状态再指定回调?">(1).如何先改状态再指定回调?</h3><ul class="lvl-0"><li class="lvl-2"><p>在执行器中直接调用 <code>resolve()/reject()</code></p></li><li class="lvl-2"><p>延迟更长时间再调用 <code>then()</code></p></li></ul><h3 id="2-什么时候才能得到数据?">(2).什么时候才能得到数据?</h3><ul class="lvl-0"><li class="lvl-2"><p>如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据</p></li><li class="lvl-2"><p>如果先改变状态,那当指定回调时,回调函数就会调用,得到数据</p></li></ul><h2 id="4-then-方法返回的新promise的结果状态由什么决定?">4.then()方法返回的新promise的结果状态由什么决定?</h2><ul class="lvl-0"><li class="lvl-2"><p>简单表达:由 <code>then()</code> 指定的回调函数执行的结果决定</p></li><li class="lvl-2"><p>详细表达:</p><ul class="lvl-2"><li class="lvl-4">如果抛出异常,新 promise 变为 rejected,reason 为抛出的异常</li><li class="lvl-4">如果返回的是非 promise 的任意值,新 promise 变为 resolved,value 为返回的值</li><li class="lvl-4">如果返回的是另一个新 promise,此 promise 的结果就会变成新 promise 的结果</li></ul></li></ul><h2 id="5-promise如何串联多个操作任务?">5.promise如何串联多个操作任务?</h2><ul class="lvl-0"><li class="lvl-2"><p>promise 的 <code>then()</code> 返回一个新的 promise,可以看成 <code>then()</code> 的链式调用</p></li><li class="lvl-2"><p>通过 <code>then()</code> 的链式调用串联多个同步/异步任务</p></li></ul><h2 id="6-promise异常传-穿透是什么?">6.promise异常传/穿透是什么?</h2><ul class="lvl-0"><li class="lvl-2"><p>当使用 promise 的 <code>then()</code> 链式调用时,可以在最后指定失败的回调,前面任何操作出了异常,都会传到最后失败的回调中处理</p></li><li class="lvl-2"><p>因为在中间的传递中,默认执行如下语句:</p></li></ul><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></pre></td><td class="code"><pre><span class="line">reason => {</span><br><span class="line"> throw reason;</span><br><span class="line">}</span><br><span class="line">等同于:</span><br><span class="line">reason => Promise.rejected(reason);</span><br></pre></td></tr></table></figure><h2 id="7-如何中断promise链?">7.如何中断promise链?</h2><ul class="lvl-0"><li class="lvl-2"><p>定义:当使用 promise 的 <code>then()</code> 链式调用时,在中间中断,不再调用后面的回调函数</p></li><li class="lvl-2"><p>方法:在回调函数中返回一个 pending 状态的 promise 对象</p></li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">return new Promise(() => {});</span><br></pre></td></tr></table></figure><h1>四、自定义Promise</h1><ul class="lvl-0"><li class="lvl-2"><p><strong style="color:red">重复观看!!!</strong></p></li></ul><h1>五、async与await</h1><ul class="lvl-0"><li class="lvl-2"><p>MDN文档点 <a target="_blank" rel="external nofollow noopener noreferrer" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction">async</a>/<a target="_blank" rel="external nofollow noopener noreferrer" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await">await</a></p></li></ul><h2 id="1-async函数">1.async函数</h2><ul class="lvl-0"><li class="lvl-2"><p>函数的返回值为 promise 对象</p></li><li class="lvl-2"><p>promise 对象的结构由 async 函数执行的返回值决定</p></li></ul><h2 id="2-await表达式">2.await表达式</h2><ul class="lvl-0"><li class="lvl-2"><p>await 右侧的表达式一般为 promise 对象,但也可以是其他的值</p><ul class="lvl-2"><li class="lvl-4">如果表达式是 promise 对象,await 返回的是 promise 成功的值</li><li class="lvl-4">如果表达式时其他值,直接将此值作为 await 的返回值</li><li class="lvl-4">如果 await 的 promise 失败了,就会抛出异常,需要通过 <code>try...catch</code> 来捕获处理</li></ul></li><li class="lvl-2"><p><strong style="color:red">注意:await 必须写在 async 函数中,但 async 函数中可以没有 await</strong></p></li></ul><h1>六、JS异步之两种队列</h1><ul class="lvl-0"><li class="lvl-2"><p>JS 中用来存储待执行回调函数的队列包含两个不同特定的队列:</p><ul class="lvl-2"><li class="lvl-4">宏队列:用来保存待执行的宏任务(回调)。如:定时器回调、DOM 事件回调、ajax 回调</li><li class="lvl-4">微队列:用来保存待执行的微任务(回调)。如:Promise 回调、MutationObserve 回调</li></ul></li><li class="lvl-2"><p>原理图如下:<br><img src="https://z3.ax1x.com/2021/07/19/WJro38.png" alt="promise02.png"></p></li><li class="lvl-2"><p>JS 执行时会区别这两个队列:</p><ul class="lvl-2"><li class="lvl-4">JS 引擎首先必须先执行所有的初始化同步任务代码</li><li class="lvl-4">每次准备取出第一个红任务执行前,都要将所有的微任务一个一个取出来执行</li></ul></li></ul><h1>七、面试题</h1><h2 id="1-题一">1.题一</h2><ul class="lvl-0"><li class="lvl-2"><p>代码如下:</p></li></ul><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></pre></td><td class="code"><pre><span class="line">setTimeout(() => {</span><br><span class="line"> console.log(1)</span><br><span class="line">},0)</span><br><span class="line">Promise.resolve().then(() => {</span><br><span class="line"> console.log(2)</span><br><span class="line">})</span><br><span class="line">Promise.resolve().then(() => {</span><br><span class="line"> console.log(3)</span><br><span class="line">})</span><br><span class="line">console.log(4)</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>输出结果为:4 2 3 1</p></li></ul><h2 id="2-题二">2.题二</h2><ul class="lvl-0"><li class="lvl-2"><p>代码如下:</p></li></ul><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></pre></td><td class="code"><pre><span class="line">setTimeout(() => {</span><br><span class="line"> console.log(1)</span><br><span class="line">},0)</span><br><span class="line">new Promise((resolve) => {</span><br><span class="line"> console.log(2)</span><br><span class="line"> resolve()</span><br><span class="line">}).then(() => {</span><br><span class="line"> console.log(3)</span><br><span class="line">}).then(() => {</span><br><span class="line"> console.log(4)</span><br><span class="line">})</span><br><span class="line">console.log(5)</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>输出结果为:2 5 3 4 1</p></li><li class="lvl-2"><p>研究:</p><ul class="lvl-2"><li class="lvl-4">首先,Promise 的执行器函数是同步执行的,所以2先打印,之后同步执行5</li><li class="lvl-4">其次,放入微队列中的是3,宏队列中的是1,且在4处时 promise 状态还为 pending,所以其待定</li><li class="lvl-4">然后,微队列中的3打印输出,此时状态更改为,resolved,4进入微队列</li><li class="lvl-4">最后,微队列中的4打印输出,宏队列中的1打印输出</li></ul></li></ul><h2 id="3-题三">3.题三</h2><ul class="lvl-0"><li class="lvl-2"><p>代码如下:</p></li></ul><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><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></pre></td><td class="code"><pre><span class="line">const first = () => (</span><br><span class="line"> new Promise((resolve, reject) => {</span><br><span class="line"> console.log(3)</span><br><span class="line"> let p = new Promise((resolve, reject) => {</span><br><span class="line"> console.log(7)</span><br><span class="line"> setTimeout(() => {</span><br><span class="line"> console.log(5)</span><br><span class="line"> resolve(6)</span><br><span class="line"> },0)</span><br><span class="line"> resolve(1)</span><br><span class="line"> })</span><br><span class="line"> resolve(2)</span><br><span class="line"> p.then((arg) => {</span><br><span class="line"> console.log(arg)</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line">)</span><br><span class="line">first().then((arg) => {</span><br><span class="line"> console.log(arg)</span><br><span class="line">})</span><br><span class="line">console.log(4)</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>输出结果为:3 7 4 1 2 5</p></li></ul><h2 id="4-题四">4.题四</h2><ul class="lvl-0"><li class="lvl-2"><p>代码如下:</p></li></ul><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><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></pre></td><td class="code"><pre><span class="line">setTimeout(() => {</span><br><span class="line"> console.log(0)</span><br><span class="line">},0)</span><br><span class="line">new Promise((resolve, reject) => {</span><br><span class="line"> console.log(1)</span><br><span class="line"> resolve()</span><br><span class="line">}).then(() => {</span><br><span class="line"> console.log(2)</span><br><span class="line"> new Promise((resolve, reject) => {</span><br><span class="line"> console.log(3)</span><br><span class="line"> resolve()</span><br><span class="line"> }).then(() => {</span><br><span class="line"> console.log(4)</span><br><span class="line"> }).then(() => {</span><br><span class="line"> console.log(5)</span><br><span class="line"> })</span><br><span class="line">}).then(() => {</span><br><span class="line"> console.log(6)</span><br><span class="line">})</span><br><span class="line">new Promise((resolve, reject) => {</span><br><span class="line"> console.log(7)</span><br><span class="line"> resolve()</span><br><span class="line">}).then(() => {</span><br><span class="line"> console.log(8)</span><br><span class="line">})</span><br></pre></td></tr></table></figure><ul class="lvl-0"><li class="lvl-2"><p>输出结果为:</p></li><li class="lvl-2"><p>研究:</p><ul class="lvl-2"><li class="lvl-4">首先根据代码执行顺序可以判断出当前同步执行的有[1 7],宏队列有[0],微队列有[2 8]</li><li class="lvl-4">然后输出[1 7 2],当2执行过后3为同步,所以输出为[1 7 2 3],此时宏队列有[0],微队列中有[8 4 6],因为2所在的代码块中返回值为 undefined,所以6已经入队列了</li><li class="lvl-4">然后输出[1 7 2 3 8 4],当4执行完后5为promise对象的回调,此时宏队列有[0],微队列中有[6 5]</li><li class="lvl-4">然后输出[1 7 2 3 8 4 6],此时宏队列有[0],微队列中有[5 8]</li><li class="lvl-4">最后输出[1 7 2 3 8 4 6 5 0]</li></ul></li></ul></div><footer class="post-footer"><div class="my_post_copyright"><script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script><script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script><script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script><p><span>本文标题:</span><a href="/Learn-Promise.html">学习笔记:Promise(尚硅谷)</a></p><p><span>文章作者:</span><a href="/" title="访问 Zhang Yangeng 的个人博客">Zhang Yangeng</a></p><p><span>发布时间:</span>2021年07月15日 - 15:07</p><p><span>最后更新:</span>2023年01月31日 - 18:01</p><p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="external nofollow noopener noreferrer" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a></p><p><span>注意事项:</span>转载请保留原文链接及作者,请尊重作者的劳动成果</p><p><span>原始链接:</span><a href="/Learn-Promise.html" title="学习笔记:Promise(尚硅谷)">https://www.wrysmile.cn/Learn-Promise.html</a> <span class="copy-path" title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="https://www.wrysmile.cn/Learn-Promise.html" aria-label="复制成功!"></i></span></p></div><script>var clipboard=new Clipboard(".fa-clipboard");$(".fa-clipboard").click(function(){clipboard.on("success",function(){swal({title:"",text:"复制成功",icon:"success",showConfirmButton:!0})})})</script><div class="reward-container"><div>坚持原创技术分享,您的支持将是对我最大的鼓励!</div><button onclick='document.querySelector(".post-reward").classList.toggle("active")'>赞赏</button><div class="post-reward"><div><img src="https://s2.ax1x.com/2019/01/28/kKrX7T.png" alt="Zhang Yangeng 微信"> <span>微信</span></div><div><img src="https://i.loli.net/2019/01/25/5c4ac75f2e5b7.jpg" alt="Zhang Yangeng 支付宝"> <span>支付宝</span></div></div></div><div class="post-tags"><a href="/tags/%E5%89%8D%E7%AB%AF/" rel="tag"><i class="fa fa-tag"></i> 前端</a> <a href="/tags/%E5%AD%A6%E4%B9%A0/" rel="tag"><i class="fa fa-tag"></i> 学习</a></div><div class="post-nav"><div class="post-nav-item"><a href="/Learn-AJAX.html" rel="prev" title="学习笔记:AJAX(尚硅谷)"><i class="fa fa-chevron-left"></i> 学习笔记:AJAX(尚硅谷)</a></div><div class="post-nav-item"><a href="/Learn-ECMA.html" rel="next" title="学习笔记:ECMAScript教程(尚硅谷)">学习笔记:ECMAScript教程(尚硅谷) <i class="fa fa-chevron-right"></i></a></div></div></footer></article></div><div class="comments" id="lv-container" data-id="city" data-uid="MTAyMC80MjQ5Ni8xOTA0Mw=="></div></div></main><footer class="footer"><div class="footer-inner"><div class="copyright">© 2019 – <span itemprop="copyrightYear">2023</span> <span class="with-love"><i class="fa fa-heart"></i> </span><span class="author" itemprop="copyrightHolder">Wrysmile</span></div><div class="wordcount"><span class="post-meta-item"><span class="post-meta-item-icon"><i class="fa fa-chart-line"></i> </span><span>站点总字数:</span> <span title="站点总字数">413k</span> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="fa fa-coffee"></i> </span><span>站点阅读时长 ≈</span> <span title="站点阅读时长">6:15</span></span></div><div class="busuanzi-count"><span class="post-meta-item" id="busuanzi_container_site_uv"><span class="post-meta-item-icon"><i class="fa fa-user"></i> </span><span class="site-uv" title="总访客量"><span id="busuanzi_value_site_uv"></span> </span></span><span class="post-meta-item" id="busuanzi_container_site_pv"><span class="post-meta-item-icon"><i class="fa fa-eye"></i> </span><span class="site-pv" title="总访问量"><span id="busuanzi_value_site_pv"></span></span></span></div><script color="0,0,255" opacity="0.5" zindex="-1" count="99" src="https://cdn.jsdelivr.net/npm/canvas-nest.js@1/dist/canvas-nest.js"></script><script type="text/javascript">!function(e,r){function t(){for(var e=0;e<n.length;e++)n[e].alpha<=0?(r.body.removeChild(n[e].el),n.splice(e,1)):(n[e].y--,n[e].scale+=.004,n[e].alpha-=.013,n[e].el.style.cssText="left:"+n[e].x+"px;top:"+n[e].y+"px;opacity:"+n[e].alpha+";transform:scale("+n[e].scale+","+n[e].scale+") rotate(45deg);background:"+n[e].color+";z-index:99999");requestAnimationFrame(t)}var o,n=[];e.requestAnimationFrame=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},function(t){var a=r.createElement("style");a.type="text/css";try{a.appendChild(r.createTextNode(t))}catch(e){a.styleSheet.cssText=t}r.getElementsByTagName("head")[0].appendChild(a)}(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o="function"==typeof e.onclick&&e.onclick,e.onclick=function(e){var t,a;o&&o(),t=e,(a=r.createElement("div")).className="heart",n.push({el:a,x:t.clientX-5,y:t.clientY-5,scale:1,alpha:1,color:"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}),r.body.appendChild(a)},t()}(window,document)</script><script type="text/javascript">var titleTime,OriginTitle=document.title;document.addEventListener("visibilitychange",function(){document.hidden?($('[rel="icon"]').attr("href","/img/TEP.ico"),document.title="╭(°A°`)╮ 页面崩溃啦 ~",clearTimeout(titleTime)):($('[rel="icon"]').attr("href","/favicon.ico"),document.title="(ฅ>ω<*ฅ) 噫又好了~"+OriginTitle,titleTime=setTimeout(function(){document.title=OriginTitle},2e3))})</script></div></footer><script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/[email protected]/dist/jquery.fancybox.min.js" integrity="sha256-yt2kYMy0w8AbtF89WXb2P1rfjcP/HTHLT7097U8Y5b8=" crossorigin="anonymous"></script><script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/bookmark.js"></script><script src="/js/third-party/search/local-search.js"></script><script class="next-config" data-name="nprogress" type="application/json">{"enable":true,"spinner":false}</script><script src="/js/third-party/nprogress.js"></script><script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><script class="next-config" data-name="leancloud_visitors" type="application/json">{"enable":true,"app_id":"mzhbgeWR9BA3SvqtvaAJulC1-gzGzoHsz","app_key":"xcGndtx2gmyop5yrT6euUk9G","server_url":null,"security":false}</script><script src="/js/third-party/statistics/lean-analytics.js"></script><script src="/js/third-party/comments/livere.js"></script></body></html>