多个异步之间的协作方案

简介: 业务逻辑可能依赖两个通过回调或事件传递

一般而言,事件与侦听器的关系是一对多,但在异步编程中,也会出现事件与侦听器的关系是多对 一的情况,也就是说一个业务逻辑可能依赖两个通过回调或事件传递

AOP 模式

lodash 就有 after,在多少次后执行,私有化预制了 timers 变量。

function after (timers, callback) {
  return function (params) {
    if (--timers === 0) {
      callback()
    }
  }
}

let newFn = after(2, function () {
  console.log('after')
})

newFn()
newFn()

以文件读取为例:

function after (timers, fn) {
  let arr = [];
  return function (data) { //  每次都会触发这个函数
    arr.push(data)
    if (--times === 0) { // 达到目的就触发
      fn(arr)
    }
  }
}

let out = after(2, function (data) {
  // 执行完成的回调
  console.log(data)
})


// 异步都有一个回调
fs.readFile('./a.txt', 'utf8', function (err, data) {
  console.log(data)
  out(data)
})
fs.readFile('./b.txt', 'utf8', function (err, data) {
  console.log(data)
  out(data)
})

发布订阅模式

function Events () {
  this.arr = []
}

Events.prototype.on = function (fn) {
  // 订阅
  this.arr.push(fn)
}

Events.prototype.emit = function (params) {
  this.arr.forEach(function (fn) {
    fn(params)
  })
}

// 多个异步并发靠的都是计数器
let e = new Events();
let arr = []
e.on(function (r) {
  if (arr.length === 2) {
      // 执行完成的回调
    console.log('ok')
  }
})

// 异步都有一个回调
fs.readFile('./a.txt', 'utf8', function (err, data) {
  console.log(data)
  e.emit(data)
})
fs.readFile('./b.txt', 'utf8', function (err, data) {
  console.log(data)
  e.emit(data)
})

Promise/Deferred 模式

let fs = require('fs');

// 实现promise延迟对象,defer
Promise.defer = function () {
  let dfd = {};
  dfd.promise = new Promise((resolve, reject) => {
    dfd.resolve = resolve;
    dfd.reject = reject;
  })
  return dfd
}

// function read () {
//   return new Promise((resolve, reject) => {
//     fs.readFile('./a.txt', 'utf8', (err, data) => {
//       if (!err) resolve(data)
//     })
//   })
// }
// 减少代码嵌套,

function read () {
  let defer = Promise.defer()
  fs.readFile('./a.txt', 'utf8', (err, data) => {
    if (!err) defer.resolve(data)
  })
  return defer.promise
}

read().then((data) => {
  console.log(data)
})

promise 化,将一个方法 promise 化,node 有个库, bluebird。

const fs = require('fs')
let bluebird = require('bluebird')

let read = bluebird.promisify(fs.readFile)

Promise.all([read('./a.txt'), read('./b.txt')]).then(data => {
  console.log(data)
})

function promisify (fn) {
  return function (...args) {
    return new Promise((resolve, reject) => {
      fn(...args, function (err, data) {
        if (!err) resolve(data)
      })
    })
  }
}
相关文章
|
8月前
|
边缘计算 JSON 物联网
解锁业务灵活性:RuleGo规则引擎的高效解耦与实时响应秘籍
RuleGo是一个基于Go语言的轻量级、高性能规则引擎,旨在通过动态规则链和组件化设计,简化复杂系统的业务逻辑管理和实时响应。
解锁业务灵活性:RuleGo规则引擎的高效解耦与实时响应秘籍
|
8月前
|
Go 调度 开发者
CSP模型与Goroutine调度的协同作用:构建高效并发的Go语言世界
【2月更文挑战第17天】在Go语言的并发编程中,CSP模型与Goroutine调度机制相互协同,共同构建了高效并发的运行环境。CSP模型通过通道(channel)实现了进程间的通信与同步,而Goroutine调度机制则确保了并发任务的合理调度与执行。本文将深入探讨CSP模型与Goroutine调度的协同作用,分析它们如何共同促进Go语言并发性能的提升。
|
3月前
|
消息中间件 缓存 监控
在FaaS中,如何设计无状态的函数来确保数据处理的一致性?
在FaaS中,如何设计无状态的函数来确保数据处理的一致性?
|
5月前
|
前端开发 JavaScript API
解锁高效应用构建:Vuex与后端交互的前端状态同步策略,让数据流动如行云流水,紧跟前端开发的热点趋势
【8月更文挑战第27天】本文深入探讨了Vue框架下的前端状态管理库Vuex与后端服务交互时的状态同步策略。通过剖析Vuex的核心机制——状态(State)、变异(Mutation)、动作(Action)及模块(Module),文章展示了如何优雅地将后端数据加载并更新至前端状态中。特别地,借助示例代码解释了Action处理API调用、Mutation更新状态的过程,并介绍了如何通过模块化和命名空间提高状态管理的准确性和时效性。此外,还讨论了组件如何利用`mapState`和`mapActions`简化状态访问与操作的方法。遵循这些策略,开发者可以在构建复杂应用时显著提升性能与用户体验。
60 0
|
6月前
|
API 开发工具 对象存储
在PAI平台上,如何实现不同编程语言任务之间的数据共享?
【7月更文挑战第1天】在PAI平台上,如何实现不同编程语言任务之间的数据共享?
136 58
|
6月前
|
Java 开发工具 git
代码协同模式使用问题之AGit-Flow协同模式是如何解决分支评审模式中特性分支过多、混乱的问题的
代码协同模式使用问题之AGit-Flow协同模式是如何解决分支评审模式中特性分支过多、混乱的问题的
|
6月前
|
存储 开发工具 Android开发
代码协同模式使用问题之创建特性分支,如何解决
代码协同模式使用问题之创建特性分支,如何解决
|
6月前
|
开发者 Windows
三类代码协同模式问题之判断项目的协同规模决定采用集成分支问题如何解决
三类代码协同模式问题之判断项目的协同规模决定采用集成分支问题如何解决
|
7月前
|
前端开发 JavaScript 数据处理
在开发复杂表单时,如何在两种模式之间进行权衡
在开发复杂表单时,如何在两种模式之间进行权衡
|
8月前
|
前端开发
第8期 volta保证团队开发环境的完全统一
第8期 volta保证团队开发环境的完全统一
54 0

热门文章

最新文章