Att arbeta korrekt med Ajax-förfrågningar i WordPress
Närhelst du arbetar med tredjeparts-API:er, och du gör det i en asynkron natur, finns det alltid en chans att vad det än är du efterfrågar kommer att returnera ett oönskat resultat.
Kanske är det en felkod, kanske är det en varning, eller så är det ett enkelt meddelande som säger något i stil med "Vi behandlar fortfarande din begäran från vår sida."
I varje fall kan du vanligtvis hantera dem på serversidan bra och låta klientsidan veta hur det ska hanteras. Men om du har att göra med det senare fallet, är det där du blockeras av tredje parts bearbetning; det finns andra saker du kan göra för att hantera den här situationen bättre.
Till exempel, i det senare fallet är det bättre att vänta en liten stund och sedan göra begäran igen för att se om API:et har ett annat svar för dig.
Men när man gör detta kräver det Ajax som uppenbarligen kräver JavaScript. En av de uppenbara, ännu mer daterade metoderna för att göra detta är att använda setInterval.
Problemet med detta är dock att det skapar en stapel av förfrågningar och sedan, när svaret är klart, kommer varje objekt i stacken att få samma svar.
Detta kan drastiskt påverka vilken server som helst. Och det finns bättre sätt att göra detta på.
Arbetar korrekt med Ajax-förfrågningar
Som vanligt, eftersom WordPress levereras med jQuery, kommer jag att använda det; Men jag uppmanar dig också – om du inte redan har gjort det – att titta på Ajax i ES6 för att få en uppfattning om hur man gör det här.
Hur som helst, tanken är denna: Istället för att ställa in något intervall, använd sedan de inbyggda Ajax-funktionerna för att utvärdera svaret ordentligt. Och bara under vissa förhållanden, aktivera funktionen igen.
Exempel: jQuerys $.post- metod erbjuder några funktioner som kan användas för just detta. Till exempel erbjuder den metoder som:
- Gjort()
- misslyckas()
- alltid()
Och var och en av dessa är avsedd att köras under vissa förhållanden som jag kommer att visa i några kodexempel tillfälligt.
Innan du gör det är det dock viktigt att förstå att det finns flera parametrar som jag skickar som jag antar att du är bekant med:
- WordPress Ajax URL (som jag kommer att definiera som acme.ajax_url),
- en URL till inlägget vi tittar på (som kommer att lagras i en sUrl-variabel),
- och ett säkerhetsmeddelande som jag kommer att kalla acme.security
Om något av ovanstående inte är klart, läs de länkade sidorna för att se hur detta uppnås.
Men med det sagt, här är idén bakom hur du kan hantera upprepade Ajax-svar utan setInterval.
1 En funktion för arbetet
Det första du behöver göra är att linda in arbetet du ska göra i sin egen funktion. Detta innebär att du kan anropa det från någon annanstans i klientsidans applikation eller till och med inom ramen för en timer (om det absolut behövs).
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// ...
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ..
});
}
Och, som du kan se, har jag gått vidare och stoppat ut några av funktionerna jag nämnde ovan.
2 Hantera framgången
I fallet med framgången kan du använda en anonym funktion som callback för $.post- funktionen. Det primära argumentet som du bör bry dig om är svarsargumentet.
Vanligtvis gillar jag att mitt svar har ett framgångsattribut och ett misslyckandeattribut. Detta gör det lättare att hantera ett ärende när svaret är helt framgångsrikt men data som kom tillbaka från servern var inte vad jag förväntade mig.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ...
});
}
Detta betyder inte nödvändigtvis att det har skett ett misslyckande. Det betyder bara att allt jag letade efter inte hittades.
3 Hantera felet
Å andra sidan finns det tillfällen då något kan misslyckas. Varför detta händer kan bero på ett antal olika anledningar och för att förstå det ordentligt är det värt att inspektera argumenten som återuppringningen ger, nämligen statusen och felet.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
cosole.log(error);
})
.always(function() {
// ...
});
}
Jag kan inte ge konkreta exempel här eftersom varje API är olika; dock rekommenderar jag åtminstone att skriva ut data till konsolen så att du kan förstå vad som händer och hur du graciöst kan hantera det på kodnivå.
4 Hantera det ovillkorliga fallet
I det här specifika fallet kommer den här funktionen att aktiveras oavsett om något lyckades eller inte.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Den här funktionen är inte något du alltid behöver (ingen ordlek), men det är ett bra alternativ för att till exempel dölja en förloppsindikator eller visa något i användargränssnittet. Detta kan ge användaren lite feedback om att begäran har slutfört sitt arbete (igen, oavsett misslyckande eller framgång).
5 Hantera framgången, igen
Slutligen, den färdiga metoden är mycket lik framgångsmetoden, men tänk på att den är avsedd att kallas en andra gång.
Det betyder att efter att svaret har kommit tillbaka från servern med svarsargumentet, kommer samma sak att aktiveras igen när allt annat har slutförts.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// Display any additional changes you may want to make based on the respnse.
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Detta ger dig ytterligare en chans att göra vad du vill med svarsargumentet en gång till innan allt är klart.
Jag använder det sällan, men det har funnits tillfällen där jag har velat ta bort ett element först efter att något gjorts, all annan bearbetning var klar och svaret lyckades.
Kanske behöver du inte allt
Uppenbarligen är mycket av koden ovan bara för en demo om hur man hanterar förfrågningar. Men syftet är att visa hur man hanterar nämnda begäran utan att behöva ställa in intervaller för att stapla förfrågningar. Istället drar du nytta av redan existerande funktioner för att till exempel anropa funktionen igen om det uppstår ett fel.
Hur som helst, detta kan vara överdrivet för vissa, men för andra som är vana vid att använda setInterval kan det vara ett mycket bättre sätt att hantera Ajax-förfrågningar som inte staplas och skickar samma begäran till servern när ett svar redan har skickats lyckades.
Och i slutändan är det målet: Effektiv kod som hämtar den information vi behöver utan att köra ner tredje parts API eller vår egen användares webbläsare.
