Javascript:如何实现异步函数队列(无需库)

2024-04-24

我一直在搜索谷歌和SO,但由于某种原因我很难解决这个问题。只是强调一下,我不想加载像 JQuery 这样的库,因为我不需要它的大部分内容。当我could使用动画库,我已经构建了我自己需要的几个函数(其中一些甚至不是您在库中找到的标准动画),所以我不确定这些是否会有帮助。事实上,我可以轻松地将这个问题命名为“如何 - 异步函数队列”,因为它不是特定于动画的。

在我的搜索中,我遇到了 Promise 的想法,但这似乎比我需要的要多一些。

我得到了一般原则 - 你有一个使用 setInterval / setTimeout 的异步函数,并且在适当的条件下,你清除间隔(如果适用)并运行回调:

function callback() {
    alert('It was just a sales call... Now where were we?');
}
function anim() {
    var i = 0,
        interval = setInterval( function() {
            // do something with the current value of i
            if (i === 100) {
                clearInterval( interval );
                callback();
            }
            i++;
        }, 50);
}

当然,如果您通过将“回调”作为 anim() 的参数来使其可重用,那就更好了。然而,我真正想做的是:

var populateDialog = new Queue([
    {fn: anim, args: ['height','300px',1500]},
    {fn: type, args: [input.value, outputDiv]},
    {fn: highlight}
]);
populateDialog.start();

第一个函数将被调用,当它完成时,队列数组中的下一个项目将被调用。问题是,虽然队列本身可以轻松地按顺序调用函数,但它需要知道当前函数的状态何时为“完成”,然后才能继续。

我需要如何设计要添加到队列中的任何函数,以便它 a) 发布其状态(以及如何让队列检测到该状态?)或 b) 可以接受来自队列的回调?我猜测前者会涉及某种自定义事件系统,而后者会更容易,看起来像:

function name(callback, param1, param2, ... paramX) {
    // setTimeout or setInterval some stuff, then call the callback argument
}

其中回调始终是第一个参数,以便可以附加任意数量的其他参数。但就像我说的,我真的很难理解所有这些,所以彻底的解释/任何替代方案将不胜感激!

EDIT

我想出的队列可以在以下位置找到我的后续问题 https://stackoverflow.com/questions/18455550/.


我需要如何设计我想要添加到队列中的任何函数,以便它a)发布其状态(以及如何让队列检测到它?)我猜它会涉及某种自定义事件系统

Exactly.

这将是一个概念Promises http://wiki.commonjs.org/wiki/Promises- 您的动画函数返回一个对象,队列可以在该对象上附加“完成”侦听器。如果您不想使用其中之一很多很多图书馆 https://github.com/promises-aplus/promises-spec/blob/master/implementations.md,您还可以实现自己的系统(简单的 pub-once/sub-often 模式)。看一下Promise/Defer 库是如何实现的? https://stackoverflow.com/questions/17718673/how-is-a-promise-defer-library-implemented(特别是first https://stackoverflow.com/revisions/17724387/1 two https://stackoverflow.com/revisions/17724387/2我的答案的修订)以获得一些灵感......

然后队列将像这样工作

var promise = queue[i].fn.apply(null, queue[i].args);
promise.then(function() {
    i++;
    // … "recurse"
});

b) 可以接受来自队列的回调吗?那会更容易,看起来像:function name(callback, param1, param2, ... paramX) {…}其中回调始终是第一个参数,以便可以附加任意数量的其他参数。

确切地。还是最后一个参数,这个比较常见。看看apply功能方法 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply用于调用具有动态数量参数的函数。

队列会是这样的

function step(i) {
    function callback() {
        step(i+1); // "recurse"
    }
    if (i < queue.length)
        queue[i].fn.apply(null, queue[i].args.concat(callback));
    // else: all done
}

但就像我说的,我真的很难理解所有这些,所以彻底的解释/任何替代方案将不胜感激!

好吧,你已经解决了——除了你概述的两种方法之外,没有其他选择。 Promise 方法更合理,对于动画函数的可变参数效果更好,而回调方法则更简单。

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

Javascript:如何实现异步函数队列(无需库) 的相关文章

  • 如何通过单击按钮从反应状态挂钩数组中删除对象

    我正在尝试制作一个按钮 根据传递的索引从数组 即状态 中删除一个对象 我已经尝试了很多 但我的方法都不起作用 所以这是代码 希望我可以找人帮忙 state const items setItems useState name quantit
  • 在不同窗口的上下文中执行函数?

    假设顶部窗口中有一个功能 例如 function z alert window name 我们还假设该文档中有一个 iframe 同源 顶部窗口中的函数是否可以在另一个窗口的上下文中执行此函数 以便它显示 iframe 的名称而不是顶部窗口
  • Angular 模板调用函数可以返回 Promise

    Angular 的 q 文档 http docs angularjs org api ng 24q说 q 承诺被模板引擎以角度方式识别 这意味着在模板中 您可以将附加到范围的承诺视为结果值 Angular 的视图模板还允许您计算表达式 这意
  • Typescript,返回元组的通用可变参数工厂函数

    在打字稿中 可以像这样创建工厂函数 并定义返回类型 function factory1
  • Iron 路由器中的多个订阅

    我一直在开发一个使用评论功能的应用程序 这导致必须订阅发表评论的集合和评论集合本身 现在看起来像这样
  • Firebase 的云功能:序列化 Promise

    在 onWrite 处理程序中 我想执行多次读取 操作一些数据 然后存储它 我对 Promise 概念还很陌生 关于 Firebase 在完成之前不会终止我的查询 我对以下 Promise 处理是否安全 exports test funct
  • 打字稿地图迭代失败

    我正在使用下面的函数来比较两个地图 有趣的是 for 循环内的代码永远不会被执行 所以 console log key val 代码永远不会被执行 当然 我确保我正在比较的映射不为空并且大小相同 以强制执行 for 循环内的代码 我犯了一个
  • IE 抛出 JavaScript TypeError 但在 chrome 上不抛出

    描述在我们的 Magento 购物车上 当用户单击添加到购物篮在任何 Internet Explorer 浏览器的 产品详细信息 页面上单击按钮 浏览器中都会弹出一个包含以下错误消息的窗口 异常 类型错误 无法获取未定义或空引用的属性 ta
  • 跨多个子域的 WebAuthn

    我正在尝试在我的网站上设置 WebAuthn 身份验证流程 但遇到了问题 我希望我的用户能够在主网站 www domain com 上注册他们的设备 以便可以通过用户设置轻松访问 身份验证本身通过 IdP sso domain com 在不
  • 需要帮助在 D3.js 条形图中将 x 轴刻度与条形对齐

    我有一个可用的线性条形图D3 js http d3js org 它也有基于时间的 x 轴 条形图绑定到计数属性 而轴绑定到日期属性 轴上的刻度未与条形对齐 知道如何将它们两者排列起来吗 这是 jsFiddle http jsfiddle n
  • 如何访问打字稿中的组件

    我有一个基本的 Angular 应用程序 如下所示 app component html h1 Test Umgebung h1 div div
  • Knockout.js——理解 foreach 和 with

    我一直在阅读 learn knockout js 教程并进行实验 有人可以解释为什么这有效吗 教程 单页应用程序 步骤 2 使用with chosenFolderData and foreach mails table class mail
  • Javascript,检测触摸设备

    我正在使用此函数来检测设备是否是触摸设备 function is touch device return ontouchstart in window onmsgesturechange in window 从这里得到这个功能 使用 Jav
  • 双向数据绑定(Angular)与单向数据流(React/Flux)

    上周 我一直在试图弄清楚如何双向数据绑定 Angular https docs angularjs org guide databinding and 单向数据流 React Flux https youtu be i 969noyAM是不
  • 如何避免JQuery和Prototype之间的冲突

    如果一个页面同时具有 JQuery 和 Prototype 那么我就会遇到冲突 有一个选项可以禁用 JQuery 的 符号 因此不会发生冲突 但是我必须使用关键字 JQuery 而不是 我想知道Prototype是否有任何选项可以解决这个冲
  • 在多个 html 文件上运行 javascript

    我有一个包含 1000 个 html 文件的文件夹 我必须使用 xpath 从每个 html 中删除某些节点 所以我已经制作了javascript 我无法打开每个文件并通过 Firefox 控制台运行 javascript 我用的是linu
  • 如何获取firestore集合下的文档数量? [复制]

    这个问题在这里已经有答案了 我想获取 firestore 集合中的文档总数 我正在制作一个论坛应用程序 所以我想显示每个讨论中当前的评论量 有类似的东西db collection comments get lenght或类似的东西 随着si
  • 如何禁用 Aloha 编辑器工具栏?

    有没有办法像侧边栏一样禁用 Aloha 的 ExtJS 工具栏 Aloha settings modules aloha aloha jquery editables editable jQuery sidebar disabled tru
  • 未捕获的类型错误:未定义不是 indexOf 上的函数

    我目前有此代码来检查特定 ID 的网站 URL GET 选项 但每当运行此代码时 我都会收到一个奇怪的错误 Uncaught TypeError Undefined is not a function 这是我的代码 如果我能得到关于这个问题
  • setInterval 会导致浏览器挂起吗?

    几年前 我被警告不要使用setInterval很长一段时间 因为如果被调用的函数运行时间超过指定的时间间隔 可能会导致浏览器挂起 然后无法跟上 setInterval function foo bar i 1 现在 我知道在循环中添加大量代

随机推荐