jQuery를 사용하여 ajax 요청을 큐잉합니다.큐()
jQuery를 사용하고 있습니다.queue()는 아직 파악하지 못했습니다.제가 뭘 잘못하고 있는지 누가 좀 지적해주시겠어요?
fire bug를 조사해도 POST 요구가 동시에 기동하고 있는 것을 알 수 있기 때문에 dequeue()를 잘못된 장소에서 호출하고 있는 것은 아닐까 생각하고 있습니다.
또한 - 큐 길이를 얻으려면 어떻게 해야 합니까?
이러한 요청을 큐잉해야 하는 이유는 버튼을 클릭하기만 하면 실행되기 때문입니다.또한 사용자는 여러 버튼을 빠르게 연속 클릭할 수 있습니다.
내 코드의 기본 구조를 제거하려고 했습니다.
$("a.button").click(function(){
$(this).doAjax(params);
});
// method
doAjax:function(params){
$(document).queue("myQueueName", function(){
$.ajax({
type: 'POST',
url: 'whatever.html',
params: params,
success: function(data){
doStuff;
$(document).dequeue("myQueueName");
}
});
});
}
「」입니다..ajax()
아약스, ①, that.ajax()
는 즉시 반환됩니다.즉, 함수를 큐잉하지만, 설명한 대로 거의 동시에 기동합니다.
난렇 i 가 아니라고 생각한다..queue()
Ajax의 .이것은, 보다 사용하기 위한 것입니다.fx methods
이치노
var ajaxManager = (function() {
var requests = [];
return {
addReq: function(opt) {
requests.push(opt);
},
removeReq: function(opt) {
if( $.inArray(opt, requests) > -1 )
requests.splice($.inArray(opt, requests), 1);
},
run: function() {
var self = this,
oriSuc;
if( requests.length ) {
oriSuc = requests[0].complete;
requests[0].complete = function() {
if( typeof(oriSuc) === 'function' ) oriSuc();
requests.shift();
self.run.apply(self, []);
};
$.ajax(requests[0]);
} else {
self.tid = setTimeout(function() {
self.run.apply(self, []);
}, 1000);
}
},
stop: function() {
requests = [];
clearTimeout(this.tid);
}
};
}());
이것은 완벽과는 거리가 멀고, 나는 단지 어떻게 해야 하는지를 보여주고 싶다.위의 예는 다음과 같은 방법으로 사용할 수 있습니다.
$(function() {
ajaxManager.run();
$("a.button").click(function(){
ajaxManager.addReq({
type: 'POST',
url: 'whatever.html',
data: params,
success: function(data){
// do stuff
}
});
});
});
저도 비슷한 일을 해야 해서 해결책을 여기에 올렸습니다.
기본적으로는 선반에 있는 프로젝트 목록 페이지입니다. 이 페이지들은 모두 독특한 기준을 가지고 있습니다.사용자가 콘텐츠를 빠르게 볼 수 있도록 모든 콘텐츠를 일일이 로드하는 것이 아니라 사용자가 읽을 수 있도록 쉘프를 하나씩 로드하는 것을 원했습니다.
기본적으로 각 쉘프의 ID를 JS 어레이에 저장하여 PHP에서 호출할 때 사용합니다.
그런 다음 첫 번째 인덱스가 호출될 때마다 배열에서 팝업되고 팝된 ID에 대한 쉘프를 요청하는 재귀 함수를 만들었습니다.$.get()
★★★★★★★★★★★★★★★★★」$.post()
콜백 내에서 재귀 함수를 호출합니다.
상세한 코드는 다음과 같습니다.
// array of shelf IDs
var shelves = new Array(1,2,3,4);
// the recursive function
function getShelfRecursive() {
// terminate if array exhausted
if (shelves.length === 0)
return;
// pop top value
var id = shelves[0];
shelves.shift();
// ajax request
$.get('/get/shelf/' + id, function(){
// call completed - so start next request
getShelfRecursive();
});
}
// fires off the first call
getShelfRecursive();
jQuery를 확장할 수 있습니다.
(function($) {
// Empty object, we are going to use this as our Queue
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
// hold the original complete function
var oldComplete = ajaxOpts.complete;
// queue our ajax request
ajaxQueue.queue(function(next) {
// create a complete callback to fire the next event in the queue
ajaxOpts.complete = function() {
// fire the original complete if it was there
if (oldComplete) oldComplete.apply(this, arguments);
next(); // run the next query in the queue
};
// run the query
$.ajax(ajaxOpts);
});
};
})(jQuery);
그 후 다음과 같이 사용합니다.
$.ajaxQueue({
url: 'doThisFirst.php',
async: true,
success: function (data) {
//success handler
},
error: function (jqXHR,textStatus,errorThrown) {
//error Handler
}
});
$.ajaxQueue({
url: 'doThisSecond.php',
async: true,
success: function (data) {
//success handler
},
error: function (jqXHR,textStatus,errorThrown) {
//error Handler
}
});
물론 $.ajax를 확장하기 때문에 유형, 데이터, contentType, DataType 등의 다른 $.ajax 옵션을 사용할 수 있습니다.
이 매우 간단한 코드를 사용하여 Ajax 콜이 서로 "추월"하지 않도록 합니다.
var dopostqueue = $({});
function doPost(string, callback)
{
dopostqueue.queue(function()
{
$.ajax(
{
type: 'POST',
url: 'thephpfile.php',
datatype: 'json',
data: string,
success:function(result)
{
dopostqueue.dequeue();
callback(JSON.parse(result));
}
})
});
}
자체를.dequeue
하다길이를 이 .
dopostqueue.queue().length
알 수 없는 수의 에이잭스 콜에 대해 이 작업을 수행해야 했습니다.정답은 각 어레이를 어레이에 밀어넣은 후 다음을 사용하는 방법은 다음과 같습니다.
$.when.apply($, arrayOfDeferreds).done(function () {
alert("All done");
});
위의 솔루션은 다소 복잡하다는 것을 알게 되었고, (새로운 데이터 토큰을 업데이트하기 위해) 전송 직전에 요청을 변경해야 했습니다.
그래서 이걸 조립했어요.출처 : https://gist.github.com/2470554
/*
Allows for ajax requests to be run synchronously in a queue
Usage::
var queue = new $.AjaxQueue();
queue.add({
url: 'url',
complete: function() {
console.log('ajax completed');
},
_run: function(req) {
//special pre-processor to alter the request just before it is finally executed in the queue
req.url = 'changed_url'
}
});
*/
$.AjaxQueue = function() {
this.reqs = [];
this.requesting = false;
};
$.AjaxQueue.prototype = {
add: function(req) {
this.reqs.push(req);
this.next();
},
next: function() {
if (this.reqs.length == 0)
return;
if (this.requesting == true)
return;
var req = this.reqs.splice(0, 1)[0];
var complete = req.complete;
var self = this;
if (req._run)
req._run(req);
req.complete = function() {
if (complete)
complete.apply(this, arguments);
self.requesting = false;
self.next();
}
this.requesting = true;
$.ajax(req);
}
};
타이머 없이 jandy의 답변의 다른 버전입니다.
var ajaxManager = {
requests: [],
addReq: function(opt) {
this.requests.push(opt);
if (this.requests.length == 1) {
this.run();
}
},
removeReq: function(opt) {
if($.inArray(opt, requests) > -1)
this.requests.splice($.inArray(opt, requests), 1);
},
run: function() {
// original complete callback
oricomplete = this.requests[0].complete;
// override complete callback
var ajxmgr = this;
ajxmgr.requests[0].complete = function() {
if (typeof oricomplete === 'function')
oricomplete();
ajxmgr.requests.shift();
if (ajxmgr.requests.length > 0) {
ajxmgr.run();
}
};
$.ajax(this.requests[0]);
},
stop: function() {
this.requests = [];
},
}
사용 방법:
$(function() {
$("a.button").click(function(){
ajaxManager.addReq({
type: 'POST',
url: 'whatever.html',
data: params,
success: function(data){
// do stuff
}
});
});
});
학습 내용jquery.com 웹사이트에도 좋은 예가 있습니다.
// jQuery on an empty object, we are going to use this as our queue
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
// Hold the original complete function
var oldComplete = ajaxOpts.complete;
// Queue our ajax request
ajaxQueue.queue(function(next) {
// Create a complete callback to invoke the next event in the queue
ajaxOpts.complete = function() {
// Invoke the original complete if it was there
if (oldComplete) {
oldComplete.apply(this, arguments);
}
// Run the next query in the queue
next();
};
// Run the query
$.ajax(ajaxOpts);
});
};
// Get each item we want to copy
$("#items li").each(function(idx) {
// Queue up an ajax request
$.ajaxQueue({
url: "/ajax_html_echo/",
data: {
html: "[" + idx + "] " + $(this).html()
},
type: "POST",
success: function(data) {
// Write to #output
$("#output").append($("<li>", {
html: data
}));
}
});
});
또한 기존 솔루션 내에서 이 작업을 수행해야 했고, 다음과 같은 방법으로 작업을 수행할 수 있었습니다.
//A variable for making sure to wait for multiple clicks before emptying.
var waitingTimeout;
$("a.button").click(function(){
$(this).doAjax(params);
clearTimeout(waitingTimeout);
waitingTimeout = setTimeout(function(){noMoreClicks();},1000);
});
// method
doAjax:function(params){
$(document).queue("myQueueName", function(next){
$.ajax({
type: 'POST',
url: 'whatever.html',
data: params,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
doStuff;
next();
},
failure: function(data){
next();
},
error: function(data){
next();
}
});
});
}
function noMoreClicks(){
$(document).dequeue("myQueueName");
}
를 next()
큐 기능으로 전달되는 콜백은 다음 조작을 큐에서 해제할 수 있습니다.따라서 Ajax의 핸들러에 다음 콜을 넣는 것으로, Ajax 콜을 브라우저 및 브라우저의 렌더링 스레드 또는 페인트 스레드에 비동기화 할 수 있지만, 서로 동기화 또는 시리얼화 할 수 있습니다.
여기 아주 기본적인 예가 있습니다.예제에서는 바이올린을 사용합니다.버튼을 한 번 클릭하고 잠시 기다립니다.타임아웃이 트리거되어 1회의 조작이 발생하는 것을 알 수 있습니다.다음으로 버튼을 가능한 한 빨리(또는 1초보다 빠르게) 클릭하면 버튼을 클릭할 때마다 작업이 큐잉되고 1초 동안 기다린 후에야 페이지가 표시되고 차례로 페이드인 되는 것을 알 수 있습니다.
이 방법의 장점은 큐가 이미 비어 있는 경우 큐에 추가한 모든 작업이 끝에 배치되고 시간이 되면 처리된다는 것입니다.
다음은 Browsergame에 대한 요청 대기열을 생성하기 위해 사용하는 솔루션입니다.무슨 일이 생기면 이 큐를 정지하고 특별한 마지막 요청이나 청소로 작업을 마칩니다.
var get_array = ["first", "second", "third"];
var worker = $("<div />"); // to line up requests in queue
$.queuedAjax = function(args){ // add up requests for me
worker.queue(
function(next){
$.ajax(args).always(next);
}
);
};
$.queuedSomething = function(){ // add up something special for me
worker.queue(
function(next){
//worker.clearQueue();
//worker = $("<div />"); //cleanup for next .each
//maybe another .each
}
);
};
$.each( get_array , function( key , value ) {
$.queuedAjax({
type: 'GET',
url: '/some.php?get='+value,
dataType: 'text',
success: function(sourcecode){
if (sourcecode.match(/stop your requests, idiot!/)) {
worker.clearQueue().queue($.queuedSomething);
alert(' the server told me to stop. i stopped all but not the last ´$.queuedSomething()´ ');
}
}
});
});
$.queuedSomething();
nodejs용으로 작성한 멀티 스레드 큐러너의 또 다른 예에 불과합니다.당신은 그것을 jquery 또는 angular에 맞출 수 있습니다.약속은 API마다 조금씩 다릅니다.이 패턴은 SharePoint의 대규모 목록에서 모든 항목을 추출하기 위해 여러 쿼리를 생성하여 모든 데이터를 가져오고 한 번에 6개를 허용함으로써 서버에 의해 제한되는 제한을 피할 수 있습니다.
/*
Job Queue Runner (works with nodejs promises): Add functions that return a promise, set the number of allowed simultaneous threads, and then run
(*) May need adaptation if used with jquery or angular promises
Usage:
var sourcesQueue = new QueueRunner('SourcesQueue');
sourcesQueue.maxThreads = 1;
childSources.forEach(function(source) {
sourcesQueue.addJob(function() {
// Job function - perform work on source
});
}
sourcesQueue.run().then(function(){
// Queue complete...
});
*/
var QueueRunner = (function () {
function QueueRunner(id) {
this.maxThreads = 1; // Number of allowed simultaneous threads
this.jobQueue = [];
this.threadCount = 0;
this.jobQueueConsumer = null;
this.jobsStarted = 0;
if(typeof(id) !== 'undefined') {
this.id = id;
}
else {
this.id = 'QueueRunner';
}
}
QueueRunner.prototype.run = function () {
var instance = this;
return new Promise(function(resolve, reject) {
instance.jobQueueConsumer = setInterval(function() {
if(instance.threadCount < instance.maxThreads && instance.jobQueue.length > 0) {
instance.threadCount++;
instance.jobsStarted++;
// Remove the next job from the queue (index zero) and run it
var job = instance.jobQueue.splice(0, 1)[0];
logger.info(instance.id + ': Start job ' + instance.jobsStarted + ' of ' + (instance.jobQueue.length + instance.jobsStarted));
job().then(function(){
instance.threadCount--;
}, function(){
instance.threadCount--;
});
}
if(instance.threadCount < 1 && instance.jobQueue.length < 1) {
clearInterval(instance.jobQueueConsumer);
logger.info(instance.id + ': All jobs done.');
resolve();
}
}, 20);
});
};
QueueRunner.prototype.addJob = function (func) {
this.jobQueue.push(func);
};
return QueueRunner;
}());
kno.js 등의 관찰 가능한 지원을 제공하는 프레임워크를 사용하여 관찰 큐를 구현할 수 있습니다.이 큐를 누르면 콜이 큐잉되고 시프트가 프로세스를 처리합니다.
녹아웃 실장은 다음과 같습니다.
var ajaxQueueMax = 5;
self.ajaxQueue = ko.observableArray();
self.ajaxQueueRunning = ko.observable(0);
ko.computed(function () {
if (self.ajaxQueue().length > 0 && self.ajaxQueueRunning() < ajaxQueueMax) {
var next = self.ajaxQueue.shift();
self.ajaxQueueRunning(self.ajaxQueueRunning() + 1);
$.ajax(next).always(function () {
self.ajaxQueueRunning(self.ajaxQueueRunning() - 1);
});
}
});
또 다른 Ajax 요청을 언제 전송해야 하는지 알려주는 관측치를 활용합니다.이 방법은 보다 일반적인 형태로 적용할 수 있습니다.
예를 들어 많은 엔트리를 취득한 녹아웃 매핑이 있지만 엔트리를 풍부하게 하기 위해 항목별로 다른 서비스를 호출해야 한다고 가정합니다(예를 들어 값 설정).
self.widgets = ko.observableArray();
ko.computed(function () {
var mapping = {
create: function (options) {
var res = ko.mapping.fromJS(options.data);
res.count = ko.observable();
// widget enrichment.
self.ajaxQueue.push({
dataType: "json",
url: "/api/widgets/" + options.data.id + "/clicks",
success: function (data) {
res.count(data);
}
});
return res;
}
};
// Initial request for widgets
$.getJSON("/api/widgets", function (data) {
ko.mapping.fromJS(data, mapping, self.widgets);
});
});
언급URL : https://stackoverflow.com/questions/4785724/queue-ajax-requests-using-jquery-queue
'programing' 카테고리의 다른 글
TypeError: 인터페이스 HTMLInputElement를 구현하지 않은 개체에서 'stepUp'이 호출되었습니다. (0) | 2023.02.26 |
---|---|
React의 useState() 훅을 사용하여 컴포넌트 간에 상태를 공유할 수 있습니까? (0) | 2023.02.26 |
UnicodeDecodeError: 'utf8' 코덱이 위치 3131에서 바이트 0x80을 디코딩할 수 없음: 잘못된 시작 바이트 (0) | 2023.02.26 |
Oracle Connection URL 기본 스키마 (0) | 2023.02.26 |
JSON 문자열을 탈출하는 방법 (0) | 2023.02.26 |