【问题标题】:JavaScript - running only one Promise for multiple requestsJavaScript - 对多个请求只运行一个 Promise
【发布时间】:2015-11-14 12:46:50
【问题描述】:

我想让对象请求一个 JavaScript 承诺,但我不希望它们创建单独的承诺。我想要实现的逻辑如下 - 检查一个承诺是否处于未决状态,如果没有,则创建一个新的承诺。这可能吗?根据文档,我无法检查承诺的状态,我只能在完成后处理它,但我不想为每个承诺请求调用处理程序,如果一个承诺的回调可以,我不想运行多个承诺响应所有过去的请求...

我试图以这种方式解决的问题是从外部服务器获取数据并在接收到数据后通过事件将其广播到多个对象。

【问题讨论】:

  • 如果您更详细地描述您尝试解决的实际问题(包括您的两个操作的代码)而不是描述您尝试自己的解决方案(请参阅XY Problem),我们可以向您展示如何正确使用 Promise 来处理它。
  • @jfriend00 有很多用例适用这种模式并且不是 XY 问题:例如 - 多位代码执行相同的请求,而您不想开始新的请求每一个,但也不想缓存这些值,因为它可能会改变。
  • @BenjaminGruenbaum - 你猜测了 OP 想要什么,你只能为你的猜测提供一个通用的解决方案。如果 OP 提供了他们的实际问题和实际代码的示例,我们不必准确猜测他们正在尝试做什么,并且可以提供更具体的答案。我建议 OP 如何使他们的问题成为一个更好的问题,这将引起更具体的答案,并且不涉及猜测他们想要什么。你可能猜对了,我真的不确定。但是,任何需要猜测的问题都可能会更好。
  • 那么,你只是想要一个使用承诺的缓存吗?那么,第一个请求数据的人创建了实际的请求,而其他人只是使用相同的结果?
  • 是的,这正是我想要的 :)

标签: javascript promise


【解决方案1】:

当然,这很容易实现

var _p = null; // just a cache
function batchRequests(fn){
    if(_p != null) return _p; // if we have an in-flight request, return it
    _p = fn(); // otherwise start a new action
    _p.then(function(){ _p = null; },  // delete cache on resolve
            function(){ _p = null; }); // even on failure
    return _p; // return the new in-flight request
}

你可以这样做:

function delay(){ // just for example, simulate a request
    return new Promise(function(resolve){ setTimeout(resolve, 1000); });
}

var batched = function(){ return batchRequests(delay); };
batched().then(function(){ console.log("All these"); });
batched().then(function(){ console.log("execute after"); });      
batched().then(function(){ console.log("one second, at the same time"); });

【讨论】:

  • 多线程会是个问题吗? (对不起,如果这是一个愚蠢的问题,我是 JavaScript 新手,我不确定这些异步函数是如何工作的,但理论上我们可以在 batchRequests 中有多个线程,它们检查全局变量是否没有承诺,然后每个线程都做出自己的承诺...)
  • 简而言之 - 不。深入 - 可能不会,除非您在 Rhino 中运行它或作为另一种语言的嵌入式语言并从该环境继承多线程问题。所以“否”适用于大多数环境(浏览器、节点等)。
  • @jamesemanon batchRequests 将函数作为参数并返回一个函数,该函数的作用类似于输入函数,只是它表现出 OP 要求的行为。一个promise代表一个值+时间并且不是一个动作。一个承诺就像一个已经开始的操作。如果batchRequests 返回了一个承诺,那么就不可能有 OP 要求的仅批处理直到解决的行为。
  • 我挖了,但我通过 babel 运行它,它会出现类型错误。好奇的。我会重新检查我有什么,也许我错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2016-01-27
  • 2015-12-04
  • 2018-06-29
  • 1970-01-01
  • 2019-07-07
相关资源
最近更新 更多