夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • javascript基础
  • javascript中的对象
  • 面向对象
  • 函数中的this
  • 异步
    • 回调
    • Promise
      • .then
      • .catch
      • .finally
      • 隐式 try...catch
    • Promise API
      • Promise.all
      • Promise.allSettled
      • Promise.race
      • Promise.any
    • Async/await
      • async
      • Await
    • event loop事件循环
    • 宏任务和微任务
  • 浏览器
  • javascript机制
  • 设计模式
  • 快速入门js
  • 《JavaScript教程》笔记
夜猫子
2022-07-26
目录

异步

# 异步

# 回调

异步执行某项功能时,我们不知道这异步什么时候结束,于是可以使用回调函数,使异步执行结束时加载我们想要执行的代码。

但是,当我们想要在回调结束在执行下一个回调,再下一个回调...,于是出现了厄运金字塔(回调地狱)。

# Promise

Promise 对象的构造器(constructor)语法如下:

let promise = new Promise(function(resolve, reject) {
  // executor(生产者代码),promise中的代码会被立即调用
});
1
2
3

resolve, reject 为其两个参数,当 executor 获得了结果,无论是早还是晚,它会调用这两个回调之一:

  • resolve(value) —— 如果任务成功完成并带有结果 value。

  • reject(error) —— 如果出现了 error,error 即为 error 对象。

    这两个函数已经由 JavaScipt 引擎预先定义,因此我们不需要创建它们。

由 new Promise 构造器返回的 promise 对象具有以下内部属性:

  • state —— 最初是 "pending",然后在 resolve 被调用时变为 "fulfilled",或者在 reject 被调用时变为 "rejected"。
  • result —— 最初是 undefined,然后在 resolve(value) 被调用时变为 value,或者在 reject(error) 被调用时变为 error。

# .then

promise.then(
  function(result) { /* 状态为成功时 */ },
  function(error) { /* 状态为错误时 */ }
);
1
2
3
4

# .catch

只捕捉错误时的状态,在报错时执行。

.catch(f) 调用是 .then(null, f) 的完全的模拟,它只是一个简写形式。

一般总是建议,Promise 对象后面要跟catch()方法,这样可以处理 Promise 内部发生的错误。

# .finally

无论 promise 的处理结果如何最终都会执行,且会将 promise 的执行结果传递给下一个处理程序,也就是说后面还可以跟 .then 和 .catch 。

# 隐式 try...catch

new Promise((resolve, reject) => {
  throw new Error("Whoops!");
}).catch(alert); // Error: Whoops!
1
2
3

类似于

try{
    //...代码逻辑
   }.catch(f)
1
2
3

其内代码出现异常,会被默认视作执行 reject

# Promise API

# Promise.all

Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000))  // 3
]).then(alert); // 1,2,3 当上面这些 promise 准备好时:每个 promise 都贡献了数组中的一个元素
1
2
3
4
5

当所有给定的 promise 都 resolve 时,新的 promise 才会 resolve,并且其结果数组将成为新 promise 的结果

且结果数组中元素的顺序与其在源 promise 中的顺序相同。即使第一个 promise 花费了最长的时间才 resolve,但它仍是结果数组中的第一个。

但只要有一个 Promise 出错那么 Promise.all() 就只会输出这一个错误

# Promise.allSettled

Promise.allSettled 与Promise类似,但其会等待所有的 promise 都被 settle,无论结果如何,

即使有 Promise 输出错误,也会获取到其他 Promise 的输出。

# Promise.race

与 Promise.all 类似,但只等待第一个 settled 的 promise 并获取其结果(或 error)。

# Promise.any

与 Promise.race 类似,区别在于 Promise.any 只等待第一个 fulfilled (resolve被调用)的 promise,并将这个 fulfilled 的 promise 返回。

# Async/await

# async

async function f() {
  return 1;
}.then(alert); // 1
1
2
3

在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。

# Await

await 只在 async 函数内工作

async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });
  let result = await promise; // 等待,直到 promise resolve (*)
  alert(result); // "done!"
}
f();//1秒后显示"done!"
1
2
3
4
5
6
7
8

关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。

# event loop事件循环

js是单线程的, 为了防止单线程的任务阻塞,就有了异步任务。

过程:

遇到同步任务,同步任务被依次压入执行栈中;

遇到异步任务,异步处理机制等异步回调结束会将异步任务加入任务队列;

当执行栈中的所有同步任务被处理完毕,异步处理机制再将任务队列中的异步任务依次加入执行栈。

而事件循环就是反复查看执行栈和任务队列的过程

# 宏任务和微任务

宏任务:setTimeout,setInterval,Ajax,DOM 事件。 微任务:Promise async/await。

两者区别:

  • 宏任务:DOM 渲染后触发,如 setTimeout 、setInterval 、DOM 事件 、script 。
  • 微任务:DOM 渲染前触发,如 Promise.then 、MutationObserver 、Node 环境下的 process.nextTick 。

而渲染是在执行栈空了之后开始,优先级比任务队列高,即渲染在下一个异步任务加入栈前执行。

注意 Promise(其构造函数)内的代码会立即执行,同同步任务表现一致。

编辑 (opens new window)
上次更新: 2023/7/11 18:57:41
函数中的this
浏览器

← 函数中的this 浏览器→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式