Javascript $timeout 的 Angular 2 等价物
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45714574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 2 equivalent for $timeout
提问by O. R. Mapper
I have to use (large amounts of) existing code in an Angular 2 environment. That code makes extensive use of the $timeoutservicefrom AngularJS 1.x. As opposed to various other AngularJS 1.x services that are used in the code, I am having a hard time finding a information about an Angular 2 equivalent for the $timeoutservice.
我必须在 Angular 2 环境中使用(大量)现有代码。该代码广泛使用了AngularJS 1.x中的$timeout服务。与代码中使用的各种其他 AngularJS 1.x 服务相反,我很难找到有关该$timeout服务的 Angular 2 等效项的信息。
The Angular docsdo not seem to contain any mention of a service with timeout-something in its name. The article Upgrading from AngularJSdoes mention the scenario I am facing:
该角文档似乎并没有包含服务提及任何与timeout在其名称-something。文章从AngularJS升级确实提到我对着场景:
Maybe you want access to AngularJS's built-in services like
$locationor$timeout.
也许您想访问 AngularJS 的内置服务,例如
$location或$timeout。
Unfortunately, the article does not actually explain how to access those particular services, as the subsequent example HeroesServiceassumes a service without any dependencies supplied by AngularJS 1.x.
不幸的是,这篇文章实际上并没有解释如何访问这些特定服务,因为后续示例HeroesService假设服务没有任何由 AngularJS 1.x 提供的依赖项。
Articles such as this onesuggest using the native setTimeoutfunctiondoes not live up to the capabilities of the $timeoutservices, either.
文章如这一个建议使用本机的setTimeout功能不辜负的功能$timeout服务,无论是。
How can I reproduce the $timeoutfunctionality in the Angular 2 environment?
如何$timeout在 Angular 2 环境中重现功能?
EDIT: As has been noted in the answers, the drawbacks of the native setTimeoutfunction are not relevant when using Angular 2. In that case, if I had the full $qfrom AngularJS 1.x, I could replicate the $timeoutfunction roughly like this:
编辑:正如答案中所指出的,setTimeout使用 Angular 2 时本机函数的缺点并不相关。在这种情况下,如果我拥有$qAngularJS 1.x的全部内容,我可以$timeout大致像这样复制该函数:
function $timeout(fn, delay) {
var result = $q.defer();
setTimeout(function () {
$q.when(fn()).then(function (v) {
result.resolve(v);
});
}, delay);
return result.promise;
}
采纳答案by Max Koretskyi
Use setTimeoutnative function. There is no need to use special services in Angular anymore. This is due to the introduction of zones, specifically NgZone.
使用setTimeout本机功能。不再需要在 Angular 中使用特殊服务。这是由于引入了区域,特别是NgZone。
Articles such as this one suggest using the native setTimeout function does not live up to the capabilities of the $timeout services, either.
诸如此类的文章建议使用本机 setTimeout 函数也不符合 $timeout 服务的功能。
Why makes you say so? The main task of $timeoutservice was to start digest after the delayed function is executed. You can see it from the sources:
为什么让你这么说?$timeout服务的主要任务是在延迟函数执行后启动digest。您可以从以下来源看到它:
function $TimeoutProvider() {
this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
function($rootScope, $browser, $q, $$q, $exceptionHandler) {
timeoutId = $browser.defer(function() {
try {
deferred.resolve(fn.apply(null, args));
} catch (e) {
...
if (!skipApply) $rootScope.$apply(); <-------------------- here
}, delay);
In Angular zone.jsintercepts all async operations and starts change detection in Angular which is kind of enhanced version of digest.
在 Angular 中zone.js拦截所有异步操作并在 Angular 中启动更改检测,这是一种摘要的增强版本。
If you need to replicate the $timeout, you can roughly do it like this:
如果你需要复制$timeout,你可以大致这样做:
function $timeout(fn, delay, ...args) {
let timeoutId;
$timeout.cancel = $timeout.cancel || function (promise) {
if (promise && promise.$$timeoutId in $timeout.promises) {
$timeout.promises[promise.$$timeoutId][1]('canceled');
delete $timeout.promises[promise.$$timeoutId];
return clearTimeout(promise.$$timeoutId);
}
return false;
};
$timeout.promises = $timeout.promises || {};
const promise = new Promise((resolve, reject) => {
timeoutId = setTimeout(function () {
try {
resolve(fn.apply(null, args));
} catch (e) {
reject(e);
} finally {
delete $timeout.promises[promise.$$timeoutId];
}
}, delay);
$timeout.promises[timeoutId] = [resolve, reject];
});
promise.$$timeoutId = timeoutId;
return promise;
}
// some basic testing
$timeout((v) => {
console.log('a', v);
}, 2000, 7);
const promise = $timeout(() => {
console.log('b');
}, 3000);
promise.catch((reason) => {
console.log(reason);
});
$timeout.cancel(promise);

