【问题标题】:Promise object traversing a method calls sequence (as return type)Promise 对象遍历方法调用序列(作为返回类型)
【发布时间】:2018-04-09 01:15:51
【问题描述】:

有这种古老/经典的方法 - 其他方法调用的方法返回结果:

method1(): ObjectX {
   if( condition1 )
      return method2();

   return undefined // or some default value;
}

method2(): ObjectX {
  let res: ObjectX;
  // some IO operations
  return res;
}

现在我想使用Promise<ObjectX>作为method2的返回类型(例如因为有一些IO操作)。

所以method2变成:

method2() : Promise<ObjectX> {
  return new Promise((resolve)=> {
     let res: ObjectX;
     // some IO operations
     resolve(res);
  })
}

问题出在方法1上。

为什么它不能是这样的:

method1() : Promise<ObjectX> {
   if( condition1) 
      return this.method2(); 

   return new Promise((reject)=> { reject(‘error’); })
}

为什么需要返回 promise 的方法不能返回另一个方法的结果(作为类似的 Promise)?

为什么它必须“打开”收到的 Promise,取出结果并用这个结果解决它自己的 Promise?

像这样:

method1() : Promise<ObjectX> {
    return new Promise((resolve, reject) => {
       if( condition1) 
          method2().then( (r) => resolve(r) ); // take out the result from received promise and resolve my own promise :(

       reject(‘error’); 
    });

}

我的意思是这行得通,但我想了解为什么以前的方法 1 行不通。

更一般地说,假设我有一个方法序列,它们相互调用并返回一个对象(返回对象遍历序列)。如果我在最后一个方法中引入 Promise - 作为结果类型,我必须大量修改序列中所有方法的代码,而不仅仅是签名和返回语句。

或者是否有其他技术可以实现这一点?

【问题讨论】:

    标签: typescript promise


    【解决方案1】:

    您的最终method1 过于复杂:

    method1() {
       if(condition1) 
          return Promise.resolve(method2());
       return Promise.reject(‘error’); 
    }
    

    不需要返回类型:typescript 会正确计算出它是Promise&lt;ObjectX&gt;

    但即使这样也过于复杂:

    async method1() {
       if(condition1) 
          return method2();
       throw 'error';
    }
    

    method1 再次具有正确的返回类型 Promise&lt;ObjectX&gt;

    无论method2() 返回ObjectX 还是Promise&lt;ObjectX&gt;,这两者都是相同的。您永远不需要仅仅为了返回它的值而“解包”一个 Promise,只需将其包装在一个新的 Promise 中,或者显式地使用 Promise.resolve() 或隐式地使用 async

    这个工作的原因和你的代码没有工作:

    return new Promise((reject)=> { reject(‘error’); })
    

    是你的新承诺返回类型为Promise&lt;{}&gt; 的东西,但返回Promise.reject(something) 的类型为Promise&lt;never&gt;

    当这些与您的Promise&lt;ObjectX&gt; 结合使用时,第一个代码给出了一个推断的返回类型Promise&lt;ObjectX | {}&gt;,它不能分配给Promise&lt;ObjectX&gt;,但使用Promise.reject() 会给您Promise&lt;ObjectX | never&gt;,它简化为Promise&lt;ObjectX&gt;因为 never 类型在您组合类型时会消失。

    如果您更改了不能非常简单地工作的代码,您可以自己看到这一点,因为这个变体本来可以工作:

    return new Promise<never>((reject)=> { reject(‘error’); })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      • 2012-05-04
      相关资源
      最近更新 更多