Typescript async/await 和 angular $q 服务
Posted
技术标签:
【中文标题】Typescript async/await 和 angular $q 服务【英文标题】:Typescript async/await and angular $q service 【发布时间】:2016-06-08 08:12:42 【问题描述】:新的 TypeScript 异步/等待功能使用 ES6 承诺。 AngularJS 使用 $q
服务承诺,但接口略有不同。
有什么方法可以使用带有$q
服务承诺的 TypeScript async/await 功能?
【问题讨论】:
是的。第一个问题是我必须将每一个来自 ng-service 的 promise-response 转换为使用 await 来对付它。第二个问题是由 await 表达式生成的 ES6-promises 不会启动角度摘要循环 关于这个github.com/Microsoft/TypeScript/issues/6122有一个未解决的问题 【参考方案1】:我认为您不能直接使用它们。但是将 q promise 转换为 a++ promise 应该很容易,如下所示:
function Convert<T>(qPromise): Promise<T>
return new Promise<T>((resolve, reject) =>
qPromise.then((result: T) => resolve(result), (e) => reject(e));
);
;
【讨论】:
问题在于,在这种情况下,我必须包装每个返回 $q 承诺的 ng 服务。此外,ES6 承诺不会启动角度摘要循环。所以,在这种情况下,我必须在每个await
之后调用 $apply
【参考方案2】:
最后我使用了以下解决方法:
declare var __awaiter: Function;
(window as any).__awaiter = __awaiter; // set global __awaiter to avoid declaring default __awaiter in other files
async () => // dummy async function to generate __awaiter code for current file
angular.module('ts-awaiter', []).run(['$timeout', ($timeout: ng.ITimeoutService) =>
function wrap(func: Function)
return function ()
func.apply(this, arguments);
$timeout(() => ); // run angular digest
;
var oldAwaiter = __awaiter;
(window as any).__awaiter = (thisArg: any, _arguments: any, P: Function, generator: any) =>
P = function (executor: Function)
return new Promise<any>((resolve, reject) =>
resolve = wrap(resolve);
reject = wrap(reject);
executor(resolve, reject);
);
;
return oldAwaiter(thisArg, _arguments, P, generator);
;
]);
Compliper for Typescript 1.8 在每个使用await
运算符的文件中生成__awaiter
函数。我将其替换为传递自定义Promise
构造函数的实现,该构造函数在每次resolve
和reject
调用后启动摘要循环。这是使用示例:https://github.com/llRandom/ts-awaiter
【讨论】:
只是出于好奇,这个句柄是如何拒绝的?捕获块? 是的。在存储库中添加了一个示例 这可能会导致不需要的摘要,而摘要是 AngularJS 应用程序性能最常见的瓶颈。并且该解决方案不适用于 TypeScript ES2017 目标...原生 async/await 已经存在。【参考方案3】:你可以让它像这样工作:
angular.module('your app')
.run(['$window', '$q', function($window, $q)
$window.Promise = $q;
]);
【讨论】:
谢谢,比我的版本简洁多了。不知道 $q 服务可以用作兼容 es6-promises 的构造函数 这行得通,我现在在几个项目中使用它。但我不禁动摇了这种调皮的感觉。用 Angular 的 $q 服务替换全局 Promise 对象似乎......hackish。 用 $q 替换原生 Promise 可能是对应用程序所能做的最糟糕的事情。它们是根本不同的实现,行为不同,这将破坏所有依赖于Promise
的第三方代码。关于“hackish”$window 的说法是错误的——它的存在不是因为 Angular 无法使用原生窗口,而是因为 DI 很好。
@estus 那么我们应该怎么做呢?我一直在网上寻找 async / await 与 AngularJS 正常工作,但我找不到一个好的共识。
@Schoof 顺便说一句,答案对原生 async
(TypeScript es2017 目标)无论如何都不起作用,因为它依赖于内部原生实现而不是 Promise
全局。例如见***.com/a/45119519/3731501。应在异步函数执行后以或多或少明确的方式触发摘要。以上是关于Typescript async/await 和 angular $q 服务的主要内容,如果未能解决你的问题,请参考以下文章
Gulp/Typescript/Async/Await 代码不起作用 - 为啥?
为啥 Typescript 认为 async/await 返回包装在承诺中的值?
实现一个 async/await (typescript 版)
TypeScript 2.1 async/await ES5 __awaiter 和 __generator 为每个 ts 文件生成