如何实现可重用的回调函数

2024-02-09

我对 JavaScript 相当陌生,我在 Node 中工作,这需要对异步编程和回调设计有很好的理解。我发现使用嵌入式函数非常容易,即使您的回调是多个级别的深度。您的嵌入式回调最终会成为闭包。

但是,当您有多层回调,其中许多回调在执行路由上是相似的时,您最终会在单独的回调链中一遍又一遍地重写大量回调代码。例如,如果下面的 mycb1 和 mycb2 定义被移到 A 之外,则它们不再具有对 A 变量的隐式访问,因此不再充当闭包。

具有嵌入定义的示例,其中它们充当闭包。

mod.A=function(){
  var mycb1=function(err){
    if (!err){
      var mycb2=function(err){
        cb(err);
      };
      mod.foo2(args,mycb2);
    }
    else{cb(err);}
  };
  mod.foo1(args,mycb1);
}

mod.foo1 = function(args,cb){
  //do some work
  cb(err);
};

mod.foo2 = function(args,cb){
  //do some work
  cb(err);
} 
//execute
mod.A();

我想要执行以下操作,但能够更改 mycb1 和 mycb2 函数的变量范围,以便它们可以在调用它们的地方用作闭包。 例如:

var mycb2=function(err){
  ...
  cb(err);
};

var mycb1=function(err){
  if (!err){        
    mod.foo2(args,mycb2);  //but have it act like a closure to mycb1
  }
  else{cb(err);}
};

mod.A=function(){
  ...
  mod.foo1(args,mycb1);  //but have it act like a closure to A
} 

mod.foo1 = function(args,cb){
  //do some work
  cb(err);
}

mod.foo2 = function(args,cb){
  //do some work
  cb(err);
}

我知道我可以实现一种在 mod 级别设置变量的设计,以便 mod 级别的函数可以访问它们。然而,这似乎在某种程度上污染了 mod 作用域,因为该变量只能由其少数方法使用。我还知道我可以传入变量,以便在执行回调时可以访问它们。但是,如果我了解 JS 和回调是如何工作的,我就必须将它们传递给 fooX,然后让 foo 将它们传递给回调。这似乎也不是一个好的计划。 是否可以更改函数的变量范围,使其从执行点而不是定义点起像闭包一样?如果没有,模块化回调代码以便可以重用的最佳方法是什么?


一般来说,必须创建另一个函数in-line可以访问闭包。您可以通过一个简单的匿名函数来创建内联函数,该函数将一些参数作为参数传递给父回调,同时接受其余参数(即部分函数),或者使用函数.bind() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind创建偏函数本身。

例如,如果您最初有:

function(...) {
    // closure vars x1, y1
    foo.bar( function(result) {
        // do something with x1 and y1
    });
}

您可以将其提取到:

var callback = function(x1, y1, result) {
    // do something with x1 and y1
};

function(...) {
    // closure vars x1, y1

    // option 1: make your own partial function
    foo.bar( function(result) { return callback(x1, y1, result); });
    // with ES6: foo.bar( (result) => callback(x1, y1, result); });

    // option 2: use Function.bind
    foo.bar( callback.bind(this, x1, y1); );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现可重用的回调函数 的相关文章

  • 如何使用 Chai Http 发布对象数组

    我正在尝试发布一个对象数组ChaiHttp https github com chaijs chai http像这样 agent post route to api send locations lat lat1 lon lon1 lat
  • 打开 md-calendar 时滚动到当前日期

    目前正在构建一个使用 Angular Material 的应用程序 我们需要一个 md calendar 组件 我们想要自定义按钮样式和内容 因此不使用普通的 md datepicker 问题是 当 md calender 打开时 滚动位置
  • 以一定时间间隔连续重复运行 JavaScript 函数

    这是我的第一个问题 希望您尽快回答 我想要代码连续重复一个函数 我尝试了一些代码 但没有成功 我尝试了这段代码 我想在一段时间后重复这个功能 我努力了setInterval and setTimeout 但是 我还没有收到结果 这将重复该任
  • Web 组件 - 服务/非 html 组件

    所以我来自 Angular 想看看如何创建vanilla Web components 现在 从 Angular 开始 我们倾向于将事物分开 组件 充当 HTML CSS 和一些 javascript 然后是 服务 主要负责收集数据和执行不
  • javascript jquery 使用脚本更改脚本的src

    我有一个 JavaScript 脚本 它有一个 src 元素 这个 src 是一个 url 我想使用 javascript 更改它 一次更改为其他内容 或者动态创建它 使用 javascript jquery 动态创建脚本元素的最佳方法是什
  • 如何动态突出显示网页上的字符串?

    我想创建带有 url 的页面 例如 http xyzcorp schedules 2015Aug24 Aug28 Jim Hawkins http xyzcorp schedules 2015Aug24 Aug28 Billy Bones
  • 如何以编程方式退出或关闭 Javascript UWP 应用程序? (Windows 10)

    我制作了一个游戏 它需要自己的退出按钮 我无法使用CoreApplication Exit https msdn microsoft com en us library windows apps windows applicationmod
  • 构建:找不到“节点”的类型定义文件

    VS 2015 社区版 在家 npm 3 10 Angular 2 我试图在 ASP Net MVC 5 应用程序中获取 Angular2 设置 我开始使用的模板使用旧版本的 Angular 因此我更新了包引用 当我构建时 列表中的第一个错
  • 一次更新猫鼬中的多个文档

    我有一个用户文档数组 每个用户都有关注者属性 它是一个数字 我只想将此属性增加 1 然后立即更新数据库中的所有这些用户文档 更多细节 在请求中 我有一组用户 id 我使用这些 id 进行查询以获取一组用户文档 const users awa
  • jQM / jquery-collagePlus 使用问题

    我正在使用 jQM 构建应用程序 并且尝试使用 jquery collagePlus http ed lea github io jquery collagePlus http ed lea github io jquery collage
  • ToggleClass 动画 jQuery?

    我的网站上有一个部分 当用户单击时我希望它展开 我正在使用 jQuerytoggleClass为了这 expandable function e e preventDefault this closest article toggleCla
  • 在管道中重用变量的功能方式

    在 javascript 和 typescript 中与 Ramda 一起使用函数式编程 我经常发现自己编写如下代码 const myFun c gt const myId c id const value pipe getAnotherO
  • 如何打开弹出窗口并用父窗口中的数据填充它?

    如何使用 JavaScript jQuery 使用父页面中 JS 变量的数据填充弹出窗口 在我的示例中 我有一个文件名数组 我在父窗口中最多列出五个 如果还有更多 我想提供一个链接来打开弹出窗口并列出数组中的每个帖子 因此 如果我打开一个包
  • 从 DirectionsRenderer 中获取折线或标记的事件

    我正在使用 DirectionsService 和路线方法来生成 DirectionsResult 我还使用 DirectionsRenderer 对象来显示结果 因为它非常易于使用 我在检测 Directions changed 事件时没
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全
  • 使用 AngularJS 多部分表单数据将文件上传到 Google Cloud Storage

    我正在尝试使用 AngularJS 中指定的多部分方法将图像文件上传到 Google Cloud Storagehttps cloud google com storage docs json api v1 how tos upload m
  • RoR - Rails 中的大文件上传

    我有一个 Rails Web 应用程序 允许用户上传视频 视频存储在 NFS 安装的目录中 当前的设置适用于较小的文件 但我也需要支持大文件上传 最多 4GB 当我尝试上传 4GB 文件时 它最终会发生 但从用户体验的角度来看很糟糕 上传开
  • Flowtype 属性“msg”缺失为 null 或未定义

    我发现 Flow 很难用 我明白那个Array find可以返回或未定义 因此 通过阅读以下内容 github Array find on Array 引发 https github com facebook flow issues 351
  • 使用 JQuery 根据下拉列表选择的值显示/隐藏控件

    我正在尝试使用 JQuery 根据下拉菜单的选定索引显示 隐藏 div 标签 但它不起作用 任何帮助将不胜感激 Thanks
  • 如何执行“sudo nvm”?

    在我的 Mac 上 我想将一些需要 su 权限的包迁移到另一个节点版本 我使用 homebrew 安装 nvm 现在我需要执行 sudo nvm 或 reinstall packages将失败 me MacBook sudo nvm sud

随机推荐