如何在 Angular 中安排任务
How to schedule a task in Angular
我必须在 angular 中创建一个组件,每小时清理一次数据库中的数据(通过服务调用),并在 HTML 中显示上次清理时间。几个问题
- 当我们从一个组件路由到另一个组件时,组件会自动销毁并丢失所有数据吗?
- 是否可以持久化数据并在将来使用它?
@Component({
selector: 'demo-app',
template:`
<button (click)="clearData()"></button>
<h2>Last synced time: {{ time }}</h2>
`
})
export class AppComponent {
public time;
constructor(private demoService: DemoService) { }
// ----> this should be triggered every hour <----
clearData() {
this.demoService.deleteData()
.subscribe((lastCleanTime) => {this.time = lastCleanTime;});
}
}
我不喜欢通过客户端来做,给它添加一个按钮是可以的运行,想象一下这些情况:
- 你有 3 个用户,所以这个任务每小时 运行 大约 3 次,如果更多呢?
- 您没有用户,所以任务永远不会运行。
我更喜欢从服务器端执行此操作,您可以通过 API 更新时间以获得最新时间,或者您可以添加 WebSocket 使其始终更新。
1 是的,当您从一个组件导航到另一个组件时,组件数据会被删除。如果你想在组件被销毁之前做一些事情,你可以使用组件的 ngOnDestroy Lifecycle 方法。
2 您可以在组件之间导航时使用该服务来存储数据。
好的,与其从用户那里获取触发器,不如每小时运行在内部查询一次数据库会更容易How to schedule a database task?请参阅此link。
答案 1. 组件作用域仅在出现在 DOM 之前可用,所以是的,一旦它超出作用域或 DOM.
就会被销毁
答案 2. 您可以使用模型或状态或局部变量来维护数据。
确实应该定期在服务器端执行数据库清理任务 运行。在我参与的 Java 个项目中,我们用 Tomcat 或使用 ServletContextListener 的 Jetty 完成了类似的任务。其他服务器,例如节点,当然有自己的机制。
您创建一个 class 实现此接口,当您的 servlet 启动或销毁时将调用其方法。
在启动方法中,您创建一个线程,每小时循环清理一次数据库,直到 servlet 被销毁:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class DBCleanupContextListener implements ServletContextListener
{
private ExecutorService threadPool;
private DBCleanupTask dbCleanupTask;
public DBCleanupContextListener()
{
threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
dbCleanupTask = new DBCleanupTask();
}
@Override
public void contextInitialized(ServletContextEvent arg0)
{
threadPool.execute(dbCleanupTask);
// submit additional tasks here if needed...
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
dbCleanupTask.shutdown();
threadPool.shutdown();
}
class DBCleanupTask implements Runnable
{
boolean finished = false;
@Override
public void run()
{
while (!finished)
{
System.out.println("db cleanup code goes here ....");
try
{
Thread.sleep(60 * 60 * 1000); // sleeps 1 hour = 60min*60sec*1000ms
}
catch (InterruptedException e)
{
finished = true;
}
}
}
public void shutdown()
{
finished = true;
}
}
}
我有 运行 此代码与 Tomcat、Jetty 和 Spring Boot。理论上它应该 运行 在任何 JavaEE 服务器上,但你需要研究如何配置 servlet。例如,在 Tomcat 上,需要将其添加到 web.xml,如 here:
所述
<web-app ...>
<listener>
<listener-class>
com.example.DBCleanupContextListener
</listener-class>
</listener>
</web-app>
我必须在 angular 中创建一个组件,每小时清理一次数据库中的数据(通过服务调用),并在 HTML 中显示上次清理时间。几个问题
- 当我们从一个组件路由到另一个组件时,组件会自动销毁并丢失所有数据吗?
- 是否可以持久化数据并在将来使用它?
@Component({
selector: 'demo-app',
template:`
<button (click)="clearData()"></button>
<h2>Last synced time: {{ time }}</h2>
`
})
export class AppComponent {
public time;
constructor(private demoService: DemoService) { }
// ----> this should be triggered every hour <----
clearData() {
this.demoService.deleteData()
.subscribe((lastCleanTime) => {this.time = lastCleanTime;});
}
}
我不喜欢通过客户端来做,给它添加一个按钮是可以的运行,想象一下这些情况:
- 你有 3 个用户,所以这个任务每小时 运行 大约 3 次,如果更多呢?
- 您没有用户,所以任务永远不会运行。
我更喜欢从服务器端执行此操作,您可以通过 API 更新时间以获得最新时间,或者您可以添加 WebSocket 使其始终更新。
1 是的,当您从一个组件导航到另一个组件时,组件数据会被删除。如果你想在组件被销毁之前做一些事情,你可以使用组件的 ngOnDestroy Lifecycle 方法。
2 您可以在组件之间导航时使用该服务来存储数据。
好的,与其从用户那里获取触发器,不如每小时运行在内部查询一次数据库会更容易How to schedule a database task?请参阅此link。
答案 1. 组件作用域仅在出现在 DOM 之前可用,所以是的,一旦它超出作用域或 DOM.
就会被销毁答案 2. 您可以使用模型或状态或局部变量来维护数据。
确实应该定期在服务器端执行数据库清理任务 运行。在我参与的 Java 个项目中,我们用 Tomcat 或使用 ServletContextListener 的 Jetty 完成了类似的任务。其他服务器,例如节点,当然有自己的机制。
您创建一个 class 实现此接口,当您的 servlet 启动或销毁时将调用其方法。 在启动方法中,您创建一个线程,每小时循环清理一次数据库,直到 servlet 被销毁:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class DBCleanupContextListener implements ServletContextListener
{
private ExecutorService threadPool;
private DBCleanupTask dbCleanupTask;
public DBCleanupContextListener()
{
threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
dbCleanupTask = new DBCleanupTask();
}
@Override
public void contextInitialized(ServletContextEvent arg0)
{
threadPool.execute(dbCleanupTask);
// submit additional tasks here if needed...
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
dbCleanupTask.shutdown();
threadPool.shutdown();
}
class DBCleanupTask implements Runnable
{
boolean finished = false;
@Override
public void run()
{
while (!finished)
{
System.out.println("db cleanup code goes here ....");
try
{
Thread.sleep(60 * 60 * 1000); // sleeps 1 hour = 60min*60sec*1000ms
}
catch (InterruptedException e)
{
finished = true;
}
}
}
public void shutdown()
{
finished = true;
}
}
}
我有 运行 此代码与 Tomcat、Jetty 和 Spring Boot。理论上它应该 运行 在任何 JavaEE 服务器上,但你需要研究如何配置 servlet。例如,在 Tomcat 上,需要将其添加到 web.xml,如 here:
所述<web-app ...>
<listener>
<listener-class>
com.example.DBCleanupContextListener
</listener-class>
</listener>
</web-app>