Add a non-jquery promise queue to reduce form update requests (particularly useful for sliders in the workflow forms)

This commit is contained in:
guerler
2021-10-14 00:21:41 -04:00
parent 11ece208ef
commit f5921df8a9
2 changed files with 45 additions and 1 deletions
@@ -175,6 +175,7 @@
</template>
<script>
import { LastQueue } from "utils/promise-queue";
import { getDatatypesMapper } from "components/Datatypes";
import { fromSimple } from "./modules/model";
import { getModule, getVersions, saveWorkflow, loadWorkflow } from "./modules/services";
@@ -287,6 +288,7 @@ export default {
},
},
created() {
this.lastQueue = new LastQueue();
getDatatypesMapper().then((mapper) => {
this.datatypesMapper = mapper;
this.datatypes = mapper.datatypes;
@@ -470,7 +472,7 @@ export default {
},
onSetData(nodeId, newData) {
const node = this.nodes[nodeId];
getModule(newData).then((data) => {
this.lastQueue.enqueue(getModule, newData).then((data) => {
node.setData(data);
});
},
+42
View File
@@ -0,0 +1,42 @@
/**
* This queue waits until the current promise is resolved and only executes the last enqueued
* promise. Promises added between the last and the currently executing promise are skipped.
* This is useful when earlier enqueued promises become obselete.
* See: https://stackoverflow.com/questions/53540348/js-async-await-tasks-queue
*/
export class LastQueue {
constructor() {
this._nextPromise = null;
this._pendingPromise = false;
}
enqueue(action, payload) {
return new Promise((resolve, reject) => {
this._nextPromise = { action, payload, resolve, reject };
this.dequeue();
});
}
async dequeue() {
if (this._pendingPromise) {
return false;
}
if (this._nextPromise) {
let item = this._nextPromise;
this._nextPromise = null;
try {
this._pendingPromise = true;
let payload = await item.action(item.payload);
this._pendingPromise = false;
item.resolve(payload);
} catch (e) {
this._pendingPromise = false;
item.reject(e);
} finally {
this.dequeue();
}
return true;
}
return false;
}
}