草庐IT

javascript - 我怎样才能让 `.then()` 保持足够长的时间以实现具有 native promise 的轮询功能?

coder 2025-03-23 原文

总结:poll()带有回调的函数可用;我还没有发现任何使用 native promise 。我试图改编一些但没有成功。我还没有解决的问题是,当 setTimeout 调用的函数的第一个实例结束而没有任何返回时, .then()监听它会将终止视为 false和一个 reject() . then()终止并且不监听以后的返回。

问题:如何最好地帮助 .then()函数坚持使用 resolve() 稍后返回或 reject()

这篇文章的其余部分是细节。阅读有帮助的内容。

可用的投票功能:我喜欢 ( https://stackoverflow.com/users/1249219/om-shankar ) Om Shankar 在 Calling a function every 60 seconds 中的回复. David Walsh 的 poll() 非常相似(位于 https://davidwalsh.name/essential-javascript-functions )。两者都使用回调并且运行良好。我发现 poll in javascript 其中包括 poll()使用 bluebird -只有 promise 。

这是我尝试使用原生 promises 实现的尝试。

/**
 * poll - checks repeatedly whether a condition exists. When the condition
 *   exists, returns a resolved standard promise. When it has checked
 *   long enough, returns a rejected standard promise.
 * @param {function} fn - a caller-supplied synchronous function that
 *   detects a condition in the environment. Returns true if the
 *   condition exists; otherwise false.
 * @param {number} timeout - maximum number of milliseconds
 *   the caller wants to check param fn();
 *   reject() the promise at the expiration of param timeout.
 * @param {number} interval - minimum number of milliseconds between
 *   calls to param fn(); resolve() the promise when param fn() first
 *   reports true.
 * @return {promise} - resolved when param fn() returns true;
 *   rejected if param timeout expires without param fn() returning true
 */
function poll(fn, timeout, interval) {
  let endTime = Number(new Date()) + (timeout || 2000)
  interval = interval || 250
  return Promise.resolve     *2
  .then(() => {      *3
    (function p(fn, endTime, interval) {
      if (fn()) { return Promise.resolve("Condition is satisfied.") }   *4
      else {
        if (Number(new Date()) <= endTime) {)     *5
          window.setTimout(p, interval, fn, endTime, interval)    *6
        }
        else {
          return Promise.reject("Past endTime; condition not satisfied")
        }
      }
    }())     *7
  })      *8
}

预期用途:

function waitIsOver() { return (<desired condition exists>) }
poll(waitIsOver, 2000, 250)        *1

我认为这是运行的方式(如果我错了请纠正我):在调用 poll() 之后在 *1,我们快速返回一个在 *2 的未决 promise ,以便 poll()知道等待。然后,我们称该 promise 为 then() * 3处的功能。函数p()开始。如果fn() (在外部已知 p()waitIsOver() )在 *4 返回真,我们很好:我们返回 resolve()poll()在 *1 得到它寻求的已解决的 promise 。

然后是不好的部分:如果fn()在 *4 处返回 false,我们在 endTime 中在 *5(这很可能;第一次调用不太可能发生在 endTime 之后),我们使用 setTimeout()在 *6 处要求 JS 在堆栈中做一个注释以实例化另一个 p()interval 之后时间。之后,第一个实例p()终止于 *7。在 *8,then()知道 p()没有返回任何东西而终止,并将条件解释为返回 falsereject() ;与 reject() , promise 已经确定,永远不会改变。但是,interval 到期后,p() 的后继实例开火了。它返回的任何东西都丢失了; promise 已定,then()在不需要的路径上发送执行后已终止。

How do I convert an existing callback API to promises?推荐使用 Promise 构造函数的方法,resolve()打电话callback() , 和 reject()打电话errback .我尝试了该技术,但遇到了与 then() 相同的问题功能在我想要之前结束。我还没有弄清楚如何制作then()像回调函数一样耐心等待。

这提出了问题。再次:

问题:如何最好地帮助 .then()函数坚持稍后从 resolve() 返回或 reject()

最佳答案

How best to help the .then() function stick around for later returns from resolve() or reject()

.then() 处理程序在底层 promise 被解决或拒绝时被调用。在此之前从未调用过它。因此,如果您想在调用 .then() 处理程序时延迟,那么您可以延迟解析或拒绝底层 promise ,直到适当的时间。

从我的评论中您可以看出,很难准确地说出您要完成的目标,因为您不只是描述您要完成的简单目标。

鉴于此,这是我对您要实现的目标的猜测。一个明确的问题可能会在几分钟内得到这样的答案。

如果你只是想重复轮询你的函数直到它返回一个真值或直到超时时间命中,你可以使用标准的 ES6 promies 来做到这一点:

function poll(fn, timeout, interval) {
    return new Promise(function(resolve, reject) {
        // set timeout timer
        var timeoutTimer = setTimeout(function() {
            clearInterval(intervalTimer);
            reject("Past endTime; condition not satisfied");
        }, timeout);

        // set polling timer
        var intervalTimer = setInterval(function() {
            if (fn()) {
                clearTimeout(timeoutTimer);
                clearInterval(intervalTimer);
                resolve("Condition is satisfied");
            }
        }, interval);
    });
}

poll(yourFounction, 5000, 100).then(function(result) {
    // succeeded here
}).catch(function(err) {
    // timed out here
})

或者,对于 Bluebird promise 库,您可以使用其 .timeout() 方法来执行此操作:

function poll(fn, timeout, interval) {
    return new Promise(function(resolve, reject) {
        // set polling timer
        var intervalTimer = setInterval(function() {
            if (fn()) {
                clearInterval(intervalTimer);
                resolve("Condition is satisfied");
            }
        }, interval);
    }).timeout(timeout, "Past endTime; condition not satisfied");
}

poll(yourFounction, 5000, 100).then(function(result) {
    // succeeded here
}).catch(function(err) {
    // timed out here
})

请注意,这两个方案都返回一个 promise,然后当 poll() 函数完成时,它们会调用 resolve 或 reject 新的 promise,然后将触发任何 .then () 处理程序被调用。


附言我应该补充一点,这一切都假设您的 fn() 是一个同步函数,它返回一个真值或假值(这就是您的代码似乎假定的)。如果您的 fn() 实际上是一个带有回调或 promise 的异步函数,那么需要将其纳入设计中。在我们编写代码以正确使用它之前,您必须向我们展示该函数的调用约定是什么。

关于javascript - 我怎样才能让 `.then()` 保持足够长的时间以实现具有 native promise 的轮询功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38797983/

有关javascript - 我怎样才能让 `.then()` 保持足够长的时间以实现具有 native promise 的轮询功能?的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  4. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  5. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  6. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  7. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  8. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  9. 怎样用一台手机做自媒体? - 2

    其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时

  10. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

随机推荐