Promise对象遍历方法调用序列(作为返回类型)



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

method1(): ObjectX {
if( condition1 )
return method2();
return undefined // or some default value;
}
method2(): ObjectX {
let res: ObjectX;
// some IO operations
return res;
}

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

因此方法2变为:

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)的结果?

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

像这样:

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作为结果类型,我必须大量修改序列中所有方法的代码,而不仅仅是签名和返回语句。

或者还有其他技术可以做到这一点?

您的最终method1过于复杂:

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

不需要返回类型:typescript将正确地计算出它是Promise<ObjectX>

但即便如此也过于复杂:

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

并且CCD_ 4再次具有CCD_。

无论method2()返回ObjectX还是Promise<ObjectX>,这两者都是相同的。您永远不应该仅仅为了返回Promise的值而"打开"它,只需要用Promise.resolve()显式地或用async隐式地将它包装在一个新的Promise中即可。

这起作用的原因和你的代码没有起作用:

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

您的新promise返回的内容类型为Promise<{}>,但返回的Promise.reject(something)具有Promise<never>类型。

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

如果你简单地更改了不起作用的代码,你可以自己看到这一点,因为这个变体会起作用:

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

最新更新