当前位置: 首页 > 知识库问答 >
问题:

在. time()链中传递Promise.join处理程序的结果

薄高懿
2023-03-14

这类似于,但不完全相同于我如何访问以前的promise结果。然后是链条?

在这种情况下,我并行发出两个异步请求,然后是第三个异步请求,这取决于前两个请求的成功与否,最后将第二个异步请求的结果传递给函数回调。

到目前为止,我已经了解了如何通过两种方式实现这一点(为了简洁起见,省略了catch语句和函数签名):

>

var foo;
Promise.join(promiseA, promiseB, function(resultsA, resultsB) {
  foo = resultsB;
  return promiseC;
})
.then(function() {
  // foo is accessible here
  callback(null, foo);
});

使用Promise.bind,但必须使用Promise.map而不是Promise.join

var targetIndex = 1;
Promise.resolve(promises)
  .bind({})
  .map(function(response, index) {
    if (index === targetIndex) {
      this.foo = response;
    }
  })
  .then(function() {
    return promiseC;
  })
  .then(function() {
    // this.foo is accessible here
    callback(null, this.foo);
  });

可以看出,选项2相当难看,因为我必须手动检查映射器的索引参数是否与我关心的promise结果的索引匹配。选项1使用范围闭包,我理解这在大多数情况下是不可取的(但在这一点上似乎是我最好的选择)。

我真正想做的是:

Promise.bind({})
  .join(promiseA, promiseB, function(resultsA, resultsB) {
     this.foo = resultsB;
     return promiseC;
  })
  .then(function() {
    // I WISH this.foo WAS ACCESSIBLE HERE!
    callback(null, this.foo);
  });

我有没有办法利用promise。加入而不是promise。映射以避免在这种情况下使用范围闭包?

共有3个答案

李勇
2023-03-14

这与我如何在中访问之前的promise结果类似,但不完全相同。然后()chain?

我觉得完全一样。只要注意你的模式就可以了。加入

Promise.join(promiseA, promiseB, function(resultsA, resultsB) {
    return promiseC;
}).then(function(resultsC) {
    // how to get A or B here?
})

相当于"deugared"代码

Promise.all([promiseA, promiseB])
.then(function([resultsA, resultsB]) { // ES6 destructuring syntax
    return promiseC;
}).then(function(resultsC) {
    // how to get A or B here?
})

考虑到这一点,我们可以一对一地应用所有的解决方案。

>

  • 上下文状态很糟糕,显式传递很麻烦,所以我在这里不详细介绍
  • 嵌套闭包比这两种方法都简单且更好:

    Promise.join(promiseA, promiseB, function(resultsA, resultsB) {
        return promiseC
        .then(function() {
            return resultsB;
        });
    }).then(callback.bind(null, null), callback);
    

    打破链条意味着你只需要使用Promise。加入两次:

    var promiseC_ = Promise.join(promiseA, promiseB, function(resultsA, resultsB) {
        return promiseC
    });
    Promise.join(promiseC_, promiseB).then(function(_, resultsB) {
        return resultsB;
    }).then(callback.bind(null, null), callback);
    

    async/await是未来的趋势,如果你使用了transpiler,你应该试试:

    (async function() {
        var [resultsA, resultsB] = await Promise.all([promiseA, promiseB]);
        var resultsC = await promiseC;
        return resultsB;
    }()).then(callback.bind(null, null), callback);
    

    但是,如果您还不想在ES6中使用transpiler,您可以使用Bluebird和发电机:

    Promise.coroutine(function* () {
        var [resultsA, resultsB] = yield Promise.all([promiseA, promiseB]);
        var resultsC = yield promiseC;
        return resultsB;
    })().then(callback.bind(null, null), callback);
    

  • 柴赞
    2023-03-14

    Node支持生成器,让我们充分利用蓝鸟的能力,实现promise。协同程序

    const yourFunciton = Promise.coroutine(function*(){
        // obtain other promises
        const a = yield getPromiseA(); // function that returns promiseA
        const b = yield getPromiseB(); // function that returns promiseB
        const c = yield calculatePromiseC(a, b); 
        return b; // or whatever value you want to return, or callback with
    });
    // call yourFunction, it returns a promise for the completion
    

    问题是,通过使用协程和现代NodeJS,我们能够完全避免嵌套和链接,并且可以以简单的同步方式编写异步代码。我们根本不需要做任何链接或嵌套范围,因为一切都在同一个范围内。

    孔安阳
    2023-03-14

    您有一个有趣的用例,因为promise需要promise在链中多步返回的结果。对于这样的“向后”问题,我推荐一个“向后”解决方案;在promiseC之后添加结果B回到链中:

    Promise.join(promiseA, promiseB, function(resultA, resultB) {
      return promiseC.then(function() {
        return resultB;
      });
    })
    .then(function(resultB) {
      callback(null, resultB);
    });
    

    理想情况下,promiseC应该产生resultB,但这现在总是可能的。

    编辑:请注意,我在这里没有故意使用嵌套promise。匿名函数只是为了传递值,而不是执行逻辑。这种方法做同样的事情:

    ...
    return promiseC.then(function() {
      callback(null, resultB); // really not what you should be doing
    });
    

    但由于它增加了一层嵌套逻辑,破坏了链接的设计原则,因此不被鼓励。

    编辑2:这可以通过使用绑定闭包来实现,比如:

    Promise.join(promiseA, promiseB).bind({})
    .then(function(resultA, resultB) {
      this.resultB = resultB;
      return promiseC;
    })
    .then(function(resultC) {
      callback(null, this.resultB);
    });
    
     类似资料:
    • 问题内容: 因此,我阅读了android AIDL文档,并对RPC在活动和服务之间的工作方式有一个大致的了解。但是,对于我的应用程序来说,实现这些功能似乎有些麻烦:基本上,我想向Service传递一个不错的处理程序,以便其线程可以将数据传递给Activity。目前,我正在通过使用静态公共成员(黑客)来解决此问题,但我更希望仅在服务的启动Intent中传递Handler对象。例如,我可以在创建时轻松

    • 我正在使用内联箭头函数来更改我的React组件中一些div的处理程序,但我知道从性能上来说这不是一个好方法。 客观地说,设置需要参数的处理程序的最有效方法是什么?这是我尝试过的: 1.内联箭头函数 2.如果我使用构造器绑定那么我怎么传递道具? 3.如果我移除箭头函数,那么在呈现器本身上调用的函数 4.如果我使用内联绑定,那么它的性能也不是最好的

    • 我需要依次执行七个不同的流程(一个接一个)。数据存储在Mysql中。我正在考虑以下选项,如果我错了,或者有更好的解决方案,请纠正我。 要求: > 需要分块处理数据。 我的解决方案和问题:数据读取: 使用JdbcCursorItemReader读取数据,因为这是性能最好的db阅读器-但是,SQL非常复杂,所以我可能不得不考虑使用JdbcTemboard的自定义ItemReader?这让我在处理数据时

    • 问题内容: 我试图将我的数据库对象传递给我的处理程序,而不是具有全局对象。但是我不知道这是否可行,我使用的是Gorilla Mux软件包,我可以看到它把闭包作为第二个参数。 然后定义了我可以使用的参数,理想情况下,我希望拥有这样的第三个参数。 有解决方法吗?还是我需要一个全局数据库对象?我是Go的新手,所以请详细说明可能的答案。 问题答案: 欢迎来到。 可以使用全局变量,特别是数据库对象。 但是,

    • 我有一个在视图上执行动画的功能。我想为此函数实现一个完成处理程序,该处理程序将在动画完成后调用。 在ViewController中... 在HudView类中... 我尝试了很多方法,但找不到正确的语法: 传递非转义参数“myCompletionHandler”到函数,期望一个@转义闭包 无法将“Void”类型的值转换为预期的参数类型“((Bool) - 闭包:使用非转义参数“myCompleti

    • 我试图通过“网络在行动”这本书来掌握网络概念。 在我看来,有几个概念解释得不太好或太模糊。因此,我想我会来这里就这些话题做一些明确的解释。 渠道管道: 所以我有一个这样的渠道管道: 对于channelInitializer,从概念上讲,我会假设该过程将按以下顺序进行: