将含$timeout的JS代码转为TS,解决setTimeout的.then问题
把AngularJS的$timeout代码转换为TypeScript(原生setTimeout)
首先,你遇到的核心问题是:原生setTimeout并不返回Promise,而AngularJS的$timeout会自动返回一个Promise,所以直接给setTimeout加.then会报错。我们需要把setTimeout包装成Promise,或者用更现代的写法来替代链式的.then逻辑。另外还要注意原代码里的this指向问题——普通function回调里的this不会绑定到你的类实例,得改用箭头函数来保留正确的上下文。
方法1:手动包装setTimeout为Promise
先写一个工具函数把setTimeout转成返回Promise的函数,这样就能像原来的$timeout一样用.then链式调用:
// 定义一个返回Promise的timeout工具函数 private timeout(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } testTS(): void { this.timeout(1) .then(() => { this.done = true; // 返回下一个Promise,实现链式调用 return this.timeout(1000); }) .then(() => { this.done = false; }); }
方法2:用async/await简化代码
如果你的TypeScript环境支持ES2017+,用async/await会让代码逻辑更直观,可读性更强:
async testTS(): Promise<void> { // 等待1毫秒 await new Promise(resolve => setTimeout(resolve, 1)); this.done = true; // 再等待1000毫秒 await new Promise(resolve => setTimeout(resolve, 1000)); this.done = false; }
要是用上刚才的工具函数,代码会更简洁:
private timeout(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } async testTS(): Promise<void> { await this.timeout(1); this.done = true; await this.timeout(1000); this.done = false; }
补充:关于this的指向问题
原JavaScript代码里的普通function回调,其实this并不是你的类实例(严格模式下甚至是undefined),只是AngularJS的$timeout内部帮你绑定了上下文。而原生setTimeout不会做这个处理,所以改用箭头函数() => { ... }就能保留当前的this指向——因为箭头函数没有自己的this,会继承外层上下文的this。
内容的提问来源于stack exchange,提问作者YourReflection
相关产品推荐
相关产品推荐

