AngularJS中$q与Promise代码迁移至Angular5+TypeScript咨询
嘿,我来帮你搞定这个AngularJS到Angular5(TypeScript)的迁移问题!AngularJS里的$q在Angular5+里完全可以用ES6原生的Promise替代,不用再依赖AngularJS的异步模块啦。先看完整的迁移方案:
原AngularJS模拟服务代码(补全你未写完的逻辑)
你的原代码大概是这样的结构:
angular.module('reports.appActivity').factory('AppActiveMockServices', ['$q', function ($q) { var appActivity; function loadappActivity(params) { var deferred = $q.defer(); var cancel = function (reason) { deferred.reject(reason || 'Request cancelled'); }; // 模拟异步加载数据 setTimeout(() => { appActivity = [ { id: 1, name: 'App A', activeUsers: 1200 }, { id: 2, name: 'App B', activeUsers: 850 } ]; deferred.resolve(appActivity); }, 200); return { promise: deferred.promise, cancel: cancel }; } return { loadappActivity: loadappActivity }; }]);
迁移后的Angular5(TypeScript)服务代码
import { Injectable } from '@angular/core'; @Injectable({ // Angular 6+推荐用providedIn: 'root'实现树摇优化,Angular5请把这个服务添加到对应模块的providers数组中 providedIn: 'root' }) export class AppActiveMockServices { private appActivity: any[]; private cancelToken: (reason?: string) => void; loadappActivity(params: any): { promise: Promise<any[]>; cancel: (reason?: string) => void } { // 用ES6原生Promise替代AngularJS的$q.defer() const promise = new Promise<any[]>((resolve, reject) => { // 保存reject方法,用于后续取消请求 this.cancelToken = reject; // 保留原有的异步模拟逻辑 setTimeout(() => { this.appActivity = [ { id: 1, name: 'App A', activeUsers: 1200 }, { id: 2, name: 'App B', activeUsers: 850 } ]; resolve(this.appActivity); }, 200); }); return { promise, cancel: (reason?: string) => { if (this.cancelToken) { this.cancelToken(reason || 'Request cancelled'); this.cancelToken = null; // 防止重复取消导致错误 } } }; } }
关键变化说明
- 服务定义方式:去掉AngularJS的
factory,改用Angular标准的@Injectable()装饰器,这是Angular5+依赖注入的基础。 - 异步逻辑替换:用ES6原生Promise完全替代
$q——原生Promise的resolve/reject回调和$q.defer()的resolve()/reject()功能完全一致,写法更符合ES规范。 - 取消请求逻辑:原代码通过
deferred.reject()实现取消,迁移后我们把Promise的reject方法保存为实例变量cancelToken,调用cancel时直接触发这个reject方法即可。 - 依赖注入配置:Angular5需要在你的
ReportsAppActivityModule的providers数组中注册这个服务;如果是Angular6+,providedIn: 'root'会自动帮你注册并支持树摇优化。
组件中使用示例
在Angular组件里调用这个服务的方式和原逻辑类似:
import { Component, OnInit } from '@angular/core'; import { AppActiveMockServices } from './app-active-mock.services'; @Component({ selector: 'app-app-activity', templateUrl: './app-activity.component.html' }) export class AppActivityComponent implements OnInit { appActivityData: any[]; errorMsg: string; constructor(private appActiveMockService: AppActiveMockServices) {} ngOnInit() { const request = this.appActiveMockService.loadappActivity({ /* 传入你的参数 */ }); request.promise .then(data => this.appActivityData = data) .catch(err => this.errorMsg = err); // 模拟用户取消请求(比如点击按钮时调用) // request.cancel('用户主动取消了请求'); } }
总结一下:Angular5+完全兼容ES6 Promise,不需要再引入$q相关模块,原生Promise的API足够覆盖$q的所有核心功能,写法更标准也更易维护。
内容的提问来源于stack exchange,提问作者Kim2018
相关产品推荐
相关产品推荐

