【问题标题】:Problem with passing context in Bluebird Promise chain在 Bluebird Promise 链中传递上下文的问题
【发布时间】:2020-06-16 09:00:22
【问题描述】:

我遇到了需要将一些值传递给 Promise 处理程序的情况。以下是情况示例

function promiseFunct(x){
    return new Promise(function(resolve, reject){
       if(x>0) resolve(x);
       else if(x==0) resolve(1);
       else resolve(0);
  });
}

promiseFunct(-100).then(function(response){
  var someObj = { len: 124 };
  return promiseFunct(response).bind(someObj);
}).then(function(response){
    if(this.len) console.log(this.len); //not getting access here, this is Window
});

我正在尝试绑定 someObj,然后在处理程序中访问它,但没有成功。是否有一些优雅的解决方案可以将一些对象传递给 Promise 处理程序,除了传递给 Promise 然后在 Promise 中解析?

【问题讨论】:

  • 绑定someObjfunction(response){ if(this.len) console.log(this.len);}
  • @ChrisLi, someObj 没有在这个范围内定义
  • someObj 来自哪里?为什么不在第二个回调中定义呢?
  • @Bergi,如果我能做到,我会做到的。让我们假设 someObj 是一些硬计算的结果。
  • @VladislavVazhenin 为什么需要将这些硬计算放在这个范围内?请提供一个使依赖关系清晰的示例。

标签: javascript promise bluebird


【解决方案1】:

找到了简单的解决方案,但不能保证它是最优雅的。

promiseFunct(-100).bind({}).then(function(response){
  this.len = 124 ;
  return promiseFunct(response);
}).then(function(response){
    if(this.len) console.log(this.len); // showing 124
});

例如,使用bind({}) 设置不会与Window 交叉的Promise 链上下文。如果我在外面有len 值,我可以使用bind({len: len}) 然后我可以使用this.propertyName 来获取或设置在下一个处理程序中使用的所需属性。

【讨论】:

    【解决方案2】:

    先看看哪里出了问题:

    promiseFunct(-100).then(function(response){
      var someObj = { len: 124 };
      return promiseFunct(response).bind(someObj);
    })
    

    then 履行处理程序返回一个绑定的承诺。

    Promise 代码等到绑定的 Promise 完成后,才将其状态(已完成或拒绝)和值(数据或拒绝原因)传递到 Promise 链中。为此,它在内部在绑定的 Promise 上调用 then 以获取其结果,并且使用绑定的 this 值调用内部处理程序 - 他们只是忽略它。

    虽然Bluebird documentation 状态

    ...此外,从绑定的 Promise 派生的 Promise 也将是具有相同 thisArg 的绑定 Promise ...

    这不适用于这种情况:承诺链中的所有承诺都是在定义链时同步创建的,在链的任何异步处理开始之前。

    由于 Promise 链仅在处理程序之间传递单个值,因此最简单的方法可能是根据需要传递具有任意数量的其他值的命名空间对象。由于后续的处理程序已经需要知道在哪里寻找额外的数据,所以应该不会有太大的变化:

    function promiseFunct(x){
        return new Promise(function(resolve, reject){
           if(x>0) resolve(x);
           else if(x==0) resolve(1);
           else resolve(0);
      });
    }
    promiseFunct(-100).then(function(response){
    console.log( "response " + response);
      var someObj = { len: 124 };
      var ns = {response, rest: someObj};
      return ns;
    }).then(function({response, rest}){
        if(rest.len) console.log(rest.len);
        console.log(response);
    }); 

    【讨论】:

    • 我仍然需要调用一些函数,它将在处理程序中返回 Promise。在您的示例中,您没有在内部调用 promise 函数。
    • 我只是以第二次调用promiseFunct为例,它可以是任何函数,它会返回Promise。但是无论如何promiseFunct会先解析0,再解析1,它返回Promise,我没看到有必要写第二个Promise函数
    • 好,不需要我删除的评论!我看到您采用的解决方案在声明承诺链时已明确绑定的承诺上调用 then - 我认为这就是文档中“派生承诺”的含义。干得好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2020-06-01
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多