我正在开发一个使用名为contentRecordHelper的库的项目。当我通过contentRecordHelper.addTitleFilter()运行一个记录对象时,它根据记录的类型用一堆不同的属性填充记录。
之前录制:
{
"_title": "Test Record",
"_type": "content",
"_id": "029828ABF"
}
在通过contentRecordHelper.addTitleFilter()运行后进行记录:
{
"_title": "Test Record",
"_type": "content",
"_id": "029828ABF",
"server_id": "VAL8378",
"client_id": "SIRIUS",
"$titleFilter":"General",
"$contentFilter": "Standard:ContentRecord",
"$contentType":"",
"$systemType":""
}
从上面可以看到,最后添加了两个属性为空的属性:$ contentType和$ systemType。那是因为这两个是由异步函数填充的,该函数在contentRecordHelper.addTitleFilter()中启动,并且在大约1000ms之后被添加。
但是,只要生成此数据,就会将其传递到网格中。如果信息更新,则必须刷新该网格,以便正确显示。幸运的是,有一个grid.refreshGrid()函数可以做到这一点。我一直在调用它超时,所以我的代码看起来像这样:
function addRecordToGrid(record: any): void {
this.contentRecordHelper.addTitleFilter(record);
this.grid.rowData.push(record);
setTimeout(() => {
this.grid.refreshGrid();
}, 1000);
}
现在严格来说这很好用,但我的一位资深开发人员向我指出,我们不应该依赖于1000毫秒的硬盘,因为在慢速后端连接的情况下,这并不总是可靠的。他说,相反,我应该使用一个承诺,以便尽快记录。$ systemType&&记录。$ contentType存在,我调用grid.refreshGrid()。他是对的 - 这很有道理。唯一的麻烦是,我以前从未写过一个承诺,几乎我可以找到的每个例子调用一些异步函数,并等待它完成。就我而言,contentRecordHelper.addTitleFilter()几乎立即完成,即使结果的某些部分直到稍后才会出现。
我怎么能写一个承诺,简单就像等待一个条件是真的,例如(记录。$ systemType&&记录。$ contentType)?如果不可能,那么使用承诺解决我的问题的最佳方式是什么?是否可以在不更改contentRecordHelper.addTitleFilter()的情况下执行此操作?该功能背后的机制非常复杂,如果我可以避免对其进行更改,这将为我节省很多压力。
我对我正在研究的项目(以及一般的打字稿)都很陌生,所以如果这很明显,我很抱歉。
答案 0 :(得分:3)
由于异步代码位于contentRecordHelper.addTitleFilter
,它不会帮助您返回承诺,因为您不知道异步操作何时结束。
Javascript是事件驱动的,没有办法等待对象,知道操作完成的唯一方法是在contentRecordHelper.addTitleFilter
中添加返回promise的代码。
你可以做的是:
function addRecordToGrid(record: any): Promise<void> {
this.contentRecordHelper.addTitleFilter(record);
return new Promise<void>((resolve, reject) => {
const check = () => {
setTimeout(() => {
if (record.$systemType && record.$contentType) {
resolve();
} else {
check();
}
}, 1000);
}
check();
});
}
然后像这样使用它:
this.addRecordToGrid(record).then(() => this.grid.rowData.push(record));
但是正如你所看到的,它只会保持循环超时直到设置属性,它实际上不知道操作已经结束。
答案 1 :(得分:3)
我怎样才能写出一个承诺,简单就是等待条件成立,例如
(record.$systemType && record.$contentType)
?
是的,那是trivially possible。但不,这不是你应该做的。您也可以使用普通setTimeout
进行轮询(只要数据不可用,只需重复推迟refreshGrid
调用),但此不是高级开发人员的意思< / em>的。
他说相反,我应该使用承诺
并且意味着contentRecordHelper.addTitleFilter()
应该在完成更新记录时返回一个承诺。然后你会写
function addRecordToGrid(record: any): void {
this.contentRecordHelper.addTitleFilter(record).then(() => {
this.grid.refreshGrid();
});
this.grid.rowData.push(record);
}
当然,不,如果不改变addTitleFilter
,这是不可能的,但是every asynchronous function returns a promise可以简单地链接到return
或0
。
答案 2 :(得分:0)
由于contentRecordHelper.addTitleFilter
函数是异步的,它应该有一些方法告诉你何时完成。要么返回Promise(正确的方式),要么采用回调(旧的方式),要么在添加标题过滤器时触发事件。
如果它没有做任何这些事情,和你无法改变它,那么你将不得不诉诸黑客 - 比如民意调查,就像在尼扎姆的回答中一样。