我们仍然使用angular 1.5.8并且我尝试编写一个函数来打破部分的长计算。由于承诺可以与返回承诺的函数链接,我想这样写:
<Target Name="BeforePublish">
<ItemGroup>
<Content Include="wwwroot\dist\**" />
<Content Include="wwwroot\lib\**" />
</ItemGroup>
</Target>
这有效,但TypeScript编译器会抱怨,因为Angular $ timeout服务接受一个返回值的函数,而不是promise:
TS2322:输入'IPromise&lt; IPromise&gt;'不能分配给'IPromise'类型。 “IPromise&lt; IResult&gt;”类型中缺少属性“add”。
有没有办法正确定义此函数中的类型?
我可以看到两个选项:
interface IResult {
add(s: string): void { ... }
}
function buildResult(): IResult { ... }
function handleItem(s: string): string { ... }
function doWork(data: string[]): ng.IPromise<IResult> {
let i = 0;
const result = buildResult();
const process = (): ng.IPromise<IResult> => {
for(let start = i; i < start + 100; ++i) {
const item = data[i];
if(!item) {
return $q.resolve(result);
}
result.add(handleItem(item));
}
return $timeout(process, 20)
}
return process();
}
any
有更好的主意吗?
答案 0 :(得分:0)
$ timeout签名是:
interface ITimeoutService {
(delay?: number, invokeApply?: boolean): IPromise<void>;
<T>(fn: (...args: any[]) => T, delay?: number, invokeApply?: boolean, ...args: any[]): IPromise<T>;
cancel(promise?: IPromise<any>): boolean;
}
(见https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/angular/index.d.ts#L603)
因此,$timeout(process, 20)
返回IPromise<IPromise<IResult>>
,抛出TS2322错误。但是你的代码如何工作?看看$ timeout实现,我们看到了答案:
...
deferred.resolve(fn.apply(null, args));
...
$timeout
创建一个新的延迟并将其解析为deferred.resolve(fn.apply(null, args));
,当fn返回一个promise时作为一个承诺链。
所以,这里的问题是$ timeout签名! $ timeout签名应该是:
interface ITimeoutService {
(delay?: number, invokeApply?: boolean): IPromise<void>;
<T>(fn: (...args: any[]) => T | IPromise<T>, delay?: number, invokeApply?: boolean, ...args: any[]): IPromise<T>;
cancel(promise?: IPromise<any>): boolean;
}
可以看到一个说明性的测试用例here。