下面给出的代码以当前形式编译并执行时没有错误 - 但是,只要第19行的'getNextAsyncTasks'的类型声明被取消注释,编译器就会崩溃并出现以下错误:
虽然我知道在这种特殊情况下如何避免它,但是当我处理代码库的其他区域时,错误会一直无声地发生。它可能很难调试,因为当我注意到它发生时,我经常做出相当多的更改,并且没有暗示这个问题可能来自何处。
理想情况下,如果有人能让我知道导致此次崩溃的原因,我会很感激,这样我就可以更好地了解如何避免它/解决它。
module abstract {
export interface ICallback {
(...args: any[]): any;
}
export interface IAsyncOp {
(callback: ICallback): any;
}
}
export class Chain {
task : abstract.IAsyncOp;
constructor(...tasks : abstract.IAsyncOp[]) {
if (tasks.length === 1) this.task = tasks[0];
else if (tasks.length > 1) this.task = cb => this.sync(() => cb.apply(null, arguments), tasks);
else this.task = cb => cb();
}
next(getNextAsyncTasks /*: (...args: any[]) => abstract.IAsyncOp*/) {
return new Chain(
(cb: abstract.ICallback) =>
this.task(
() => getNextAsyncTasks.apply(null, arguments)(cb);
)
);
}
last(cb : abstract.ICallback) {
this.task(cb);
}
sync(cb: (...resultArgs: IArguments[]) => void, tasks: abstract.IAsyncOp[]) {
var resultArgs : IArguments[] = [], done = 0;
var getCb = (i) => {
return () => {
resultArgs[i] = arguments;
done++;
if (done === tasks.length) cb.apply(null, resultArgs);
}
};
for (var i = 0, op; op = tasks[i]; i++) op(getCb(i));
}
}
// use example
new Chain( cb => setTimeout(() => cb("foo"), 60)
, cb => setTimeout(() => cb("bar"), 10)
).next((op1, op2) => { console.log(op1, op2)
; return cb => setTimeout(() => cb(op1[0], op2[0]), 120)
}
).next((foo, bar) => { console.log(foo, bar)
; return cb => setTimeout(() => cb(foo, bar, "baz"), 30)
}
).last((foo, bar, baz) => console.log(foo, bar, baz));
编辑:更新了“下一步”,因此参数的类型签名始终是正确的。