我需要帮助来制定一个好的路由器轮询策略。queries/:query_id/results/:result_id
每当用户执行查询时,我都会转换到一条路线。在这个我的路线中,我需要加载两件事:result
与此路线关联的模型和table
使用结果模型中的 url 的对象。问题是,如果查询长时间运行,我需要轮询并询问服务器查询是否完成。只有这样我才能下载表格。我正在使用 ember 并发进行所有轮询,除了一个小的边缘情况外,它工作得很好。这种边缘情况与以下事实有关:如果我的轮询函数在完成后被取消并且在下载表时被取消,那么它会卡住说“正在加载表”,因为它只在查询状态时触发轮询没有完成。表的下载发生在轮询函数内部,但仅在查询完成时进行。我正在结果路径中加载所有数据,所以也许有人可以提供一些替代方案来做到这一点。我还需要提一下,每个表都将显示在单独的选项卡(引导选项卡)中。因此,当我在选项卡之间切换时,我想尽量减少获取表格的次数(为什么我将其推送到商店),因为每个选项卡都是指向新结果路由的链接。
结果路由中的相关代码
import Route from "@ember/routing/route";
import { inject as service } from "@ember/service";
import { reject } from "rsvp";
import { task } from "ember-concurrency";
import { encodeGetParams } from "gtweb-webapp-v2/utils";
export default Route.extend({
poller: service("poller"),
fetchResults: task(function*(result_id) {
try {
const result = yield this.store.findRecord("result", result_id);
if (result.status === "COMPLETED") {
const adapter = this.store.adapterFor("application");
const queryString = encodeGetParams({ parseValues: true, max: 25 });
const table = {
table: yield adapter.fetch(
`${result._links.table.href}?` + queryString
)
};
// Cache the table that we fetched so that we dont have to fetch again if we come back to this route.
this.store.push({
data: [
{
id: result_id,
type: "result",
attributes: table,
relationships: {}
}
]
});
return true;
}
} catch (err) {
return reject(err);
}
}),
model(params) {
const result = this.store.peekRecord("result", params.result_id);
if (!result || result.status !== "COMPLETED") {
const poller = this.get("poller");
poller.startTask(this.get("fetchResults"), {
pollingArgs: [params.result_id],
onComplete: () => {
this.refresh(); // If we finish polling or have timeout, refresh the route.
}
});
}
return result;
},
setupController(controller, model) {
const query = { title: this.modelFor("queries.query").get("title") };
controller.set("query", query);
this._super(controller, model);
},
actions: {
willTransition() {
const poller = this.get("poller");
poller.abort(); // Task was canceled because we are moving to a new result route.
}
}
});
主意
一个想法可能是创建一个单独的路径来加载表queries/:query_id/results/:result_id/:table_id
,即只有在查询完成后才转换到这个路径。从那里我可以安全地加载桌子。我唯一遇到的问题是结果路由将只涉及加载结果。在结果路由中将不会呈现任何组件;仅在表路由中。