gpt4 book ai didi

javascript - 在单线程环境中这种 Jquery 行为如何可能?

转载 作者:行者123 更新时间:2023-11-28 03:45:23 25 4
gpt4 key购买 nike

首先,任务:我需要在服务器上针对每次击键进行一系列验证。这是通过 AJAX 实现的。因此出现的问题是,如果服务器在最终(有效)响应之后发送倒数第二个(无效)响应怎么办?我们的 Javascript 代码看起来就像我们刚刚发送了无效响应。因此,我尝试实现某种队列管理器,该队列管理器将使之前的 ajax 请求过期,这样,如果它们从服务器返回,它们就不会被处理。这是相关代码(抱歉,它是用 Typescript 编写的)

class AjaxManager {
constructor(private options: AjaxOptions) {

}
_requests : Array<AjaxObject> = new Array<AjaxObject>();

send(settings: JQueryAjaxSettings, block : boolean) {
let request = $.ajax(settings);
var aO = new AjaxObject(request, settings, block);
request.always((data) => {
this.pruneEarlierRequests(aO);
});
this._requests.push(aO);
}

private pruneEarlierRequests(ajaxObject: AjaxObject) {
var requestedIndex = this._requests.findIndex((search) => { return search.id === ajaxObject.id; });

if ( requestedIndex === -1)
return; //don't prune if this request doesn't even exist here, probably an error.
if (this._requests[requestedIndex] == undefined)
return;
var data = this._requests[requestedIndex].settings.data.text;
console.log("pruning " + data);
for (var index = 0; index < this._requests.length; index++) {
console.log("processing " + data + ", index: " + index);
if (this._requests[index].id !== ajaxObject.id) {
console.log("aborted and pruned " + this._requests[index].settings.data.text + " at index " + index + ", currently processing " + data + " at index " + requestedIndex);
this._requests[index].request.abort();
} else {
console.log("pruned " + this._requests[index].settings.data.text + " at index " + index + ", currently processing " + data + " at index " + requestedIndex);
break;
}
}
}
}

class AjaxObject {
id: string;

constructor(public request: JQueryXHR, public settings : JQueryAjaxSettings, public block : boolean) {
this.id = this.guid();
}
guid() {
let _p8 = (s = false) : string=> {
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
}
return "{" + _p8() + _p8(true) + _p8(true) + _p8() + "}";
}
}

基本思想是,因为 JS 是单线程的,所以我们总是按照用户键入请求的顺序发起发送请求。然后,当我们收到 ajax 调用的响应时,我们将中止所有前面的条目.

现在,因为我假设(我可能是错的),给定输入 123,我假设如下我们的requests中有5个元素,对应1,12,123然后:

trim 12(它在1之前到达)中止并 trim 1 trim 12

trim 1 trim 1

trim 123中止并 trim 1中止和 trim 12 trim 123

相反,这就是问题所在,我得到的输出似乎表明这些 promise 是在不同的线程上处理的(我删除了一些条目)

pruning vancouve

processing vancouve, index: 0

aborted and pruned at index 0, currently processing vancouve at index 8

processing vancouve, index: 1

aborted and pruned v at index 1, currently processing vancouve at index 8

processing vancouve, index: 2

aborted and pruned va at index 2, currently processing vancouve at index 8

processing vancouve, index: 3

aborted and pruned van at index 3, currently processing vancouve at index 8

processing vancouve, index: 4

aborted and pruned vanc at index 4, currently processing vancouve at index 8

processing vancouve, index: 5

aborted and pruned vanco at index 5, currently processing vancouve at index 8

processing vancouve, index: 6

aborted and pruned vancou at index 6, currently processing vancouve at index 8

pruning vancou

processing vancou, index: 0

aborted and pruned at index 0, currently processing vancou at index 6

processing vancou, index: 1

aborted and pruned v at index 1, currently processing vancou at index 6

processing vancou, index: 2

aborted and pruned va at index 2, currently processing vancou at index 6

processing vancou, index: 3

aborted and pruned van at index 3, currently processing vancou at index 6

processing vancou, index: 4

aborted and pruned vanc at index 4, currently processing vancou at index 6

processing vancou, index: 5

aborted and pruned vanco at index 5, currently processing vancou at index 6

processing vancou, index: 6

pruned vancou at index 6, currently processing vancou at index 6

processing vancouve, index: 7

aborted and pruned vancouv at index 7, currently processing vancouve at index 8

pruning vancouv

processing vancouv, index: 0

aborted and pruned at index 0, currently processing vancouv at index 7

processing vancouv, index: 1

aborted and pruned v at index 1, currently processing vancouv at index 7

processing vancouv, index: 2

aborted and pruned va at index 2, currently processing vancouv at index 7

processing vancouv, index: 3

aborted and pruned van at index 3, currently processing vancouv at index 7

processing vancouv, index: 4

aborted and pruned vanc at index 4, currently processing vancouv at index 7

processing vancouv, index: 5

aborted and pruned vanco at index 5, currently processing vancouv at index 7

processing vancouv, index: 6

aborted and pruned vancou at index 6, currently processing vancouv at index 7

processing vancouv, index: 7

pruned vancouv at index 7, currently processing vancouv at index 7

processing vancouve, index: 8

pruned vancouve at index 8, currently processing vancouve at index 8

完全出乎我的意料,在处理索引 8(温哥华)的响应的过程中,它处理了索引 6 和索引 7 的响应。现在,我预计 8 会在 6 和 7 之前到达,但我假设在 6 和 7 的处理开始之前,8 的处理已完全完成。那么我的问题是,为什么会发生这种情况,以及如何确保每个响应的处理完全完成?

我思考过这是否只是console.log的一个属性,但处理顺序实际上影响了逻辑(有时后面的请求会被前面的请求取消)。

感谢您的帮助。

最佳答案

经过测试,似乎.abort导致.always回调被同步调用,从而导致在处理原始循环的过程中开始一个新的循环。对此的快速解决方法是执行任何操作,将该调用推送到 .abort,或者将对 pruneAbortedRequests 的调用推送到回调队列,这样就不会调用直到前一个函数运行完毕。

例如,将其包装在 setTimeout 中。

request.always((data) => {
setTimeout(() => this.pruneEarlierRequests(aO), 0);
});

除了不中止请求并使用不同的技术来减少请求数量之外,我没有立即看到比这样更好的解决方案。

关于javascript - 在单线程环境中这种 Jquery 行为如何可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48531508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com