IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 同步函数与异步函数混用可能造成的问题 -> 正文阅读

[JavaScript知识库]同步函数与异步函数混用可能造成的问题

在这里插入图片描述
上面这段函数会遍历 listeners所有的listener(监听器), 而listener又是通过函数返回的对象中的 onDataReady 方法添加的

传给 inconsistentRead 函数的第二个参数是一个回调函数, 它的执行时机应该是等待所有的 onDataReady 方法执行完成再执行, 这样才有意义

inconsistentRead 是一个同步调用与异步调用混用的函数

  • 如果 cache 中有值, 直接调用传入的回调函数
  • 如果 cache 中没有值, 通过 readFile 读取传入的文件内容, 当获取到文件内容之后, 给 cache 设置值, 并调用回调函数
import { readFile } from 'fs'

const cache = new Map()

function inconsistentRead(filename, cb) {
  if (cache.has(filename)) {
  	// 同步执行
    cb(cache.get(filename))
  } else {
  	// 异步执行
    readFile(filename, 'utf8', (err, data) => {
      cache.set(filename, data)
      cb(data)
    })
  }
}

function createFileReader(filename) {
  // inconsistentRead 内的回调, 同步执行时, listeners 为空, forEach listeners 无意义
  const listeners = []
  inconsistentRead(filename, value => {
    listeners.forEach(listener => listener(value))
  })
  return {
    onDataReady: listener => listeners.push(listener)
  }
}

const reader1 = createFileReader('data.txt')	
// 异步执行: 等所有 reader1.onDataReady 完成后, 才会执行
// 此时 listeners 存在 reader1.onDataReady 方法 push 的函数
reader1.onDataReady(data => {	// 添加 listener 到 listeners
  console.log(`123 call data: ${data}`)
})
reader1.onDataReady(data => {	// 添加 listener 到 listeners
  console.log(`456 call data: ${data}`)
})
reader1.onDataReady(data => {	// 添加 listener 到 listeners
  console.log(`789 call data: ${data}`)
  // 此时 cache 已存在 data, 依次为同步执行, 立即遍历 `listeners` 中`所有的listener(监听器)`
  const reader2 = createFileReader('data.txt')	
  reader2.onDataReady(data => {		// 现在添加已经无意义, 因为根本不会执行
    console.log(`Second call data: ${data}`)
  })
})

在这里插入图片描述

输出结果如下: reader2.onDataReady 内的回调未执行
在这里插入图片描述

所以, 一个函数中, 要么全是同步, 要么全是异步

同步读取函数

function consistentReadSync (filename) {
  if (cache.has(filename)) {
    return cache.get(filename)
  } else {
    const data = readFileSync(filename, 'utf8')
    cache.set(filename, data)
    return data
  }
}
console.log(consistentReadSync('data.txt'))
console.log(consistentReadSync('data.txt'))

在这里插入图片描述

异步读取函数

import { readFile } from 'fs'

const cache = new Map()

function consistentReadAsync(filename, callback) {
  if (cache.has(filename)) {
    process.nextTick(() => callback(cache.get(filename)))
  } else {
    // asynchronous function
    readFile(filename, 'utf8', (err, data) => {
      cache.set(filename, data)
      callback(data)
    })
  }
}

function createFileReader(filename) {
  const listeners = []
  consistentReadAsync(filename, value => {
    listeners.forEach(listener => listener(value))
  })

  return {
    onDataReady: listener => listeners.push(listener)
  }
}

const reader1 = createFileReader('data.txt')
reader1.onDataReady(data => {
  console.log(`123 call data: ${data}`)
})
reader1.onDataReady(data => {
  console.log(`456 call data: ${data}`)
})
reader1.onDataReady(data => {
  console.log(`789 call data: ${data}`)
  const reader2 = createFileReader('data.txt')
  reader2.onDataReady(data => {
    console.log(`Second call data: ${data}`)
  })
})

在这里插入图片描述
来自 <Nodejs设计模式-第三版> 第三章-回调与事件

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 16:08:57  更:2022-04-06 16:09:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:14:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码