{"id":229668,"date":"2022-11-24T09:38:00","date_gmt":"2022-11-24T06:38:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229668"},"modified":"2022-11-09T15:51:39","modified_gmt":"2022-11-09T12:51:39","slug":"prawidlowa-praca-z-zadaniami-ajax-w-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/prawidlowa-praca-z-zadaniami-ajax-w-wordpress\/","title":{"rendered":"Prawid\u0142owa praca z \u017c\u0105daniami Ajax w WordPress"},"content":{"rendered":"\n<p>Za ka\u017cdym razem, gdy pracujesz z interfejsami API innych firm i robisz to w spos\u00f3b asynchroniczny, zawsze istnieje szansa, \u017ce \u200b\u200bniezale\u017cnie od tego, o co prosisz, zwr\u00f3ci niepo\u017c\u0105dany wynik.<\/p>\n<p>By\u0107 mo\u017ce jest to kod b\u0142\u0119du, mo\u017ce to ostrze\u017cenie, a mo\u017ce jest to prosta wiadomo\u015b\u0107 o tre\u015bci typu \u201eNadal przetwarzamy Twoje \u017c\u0105danie po naszej stronie&quot;.<\/p>\n<p>W ka\u017cdym przypadku zwykle mo\u017cesz sobie z nimi poradzi\u0107 po stronie serwera i da\u0107 zna\u0107 stronie klienta, jak sobie z tym poradzi\u0107. Ale je\u015bli masz do czynienia z tym drugim przypadkiem, jest to miejsce, w kt\u00f3rym jeste\u015b blokowany przez przetwarzanie przez stron\u0119 trzeci\u0105; s\u0105 inne rzeczy, kt\u00f3re mo\u017cesz zrobi\u0107, aby lepiej poradzi\u0107 sobie z t\u0105 sytuacj\u0105.<\/p>\n<p>Na przyk\u0142ad w tym drugim przypadku lepiej poczeka\u0107 chwil\u0119, a nast\u0119pnie ponownie wykona\u0107 \u017c\u0105danie, aby sprawdzi\u0107, czy interfejs API ma dla Ciebie inn\u0105 odpowied\u017a.<\/p>\n<p>Ale kiedy to robi, wymaga Ajax, kt\u00f3ry oczywi\u015bcie wymaga JavaScript. Jedn\u0105 z oczywistych, ale bardziej przestarza\u0142ych metod jest u\u017cycie setInterval.<\/p>\n<p>Problem polega jednak na tym, \u017ce tworzy on stos \u017c\u0105da\u0144, a nast\u0119pnie, gdy odpowied\u017a jest gotowa, ka\u017cdy element stosu otrzyma t\u0119 sam\u0105 odpowied\u017a.<\/p>\n<p>Mo\u017ce to drastycznie wp\u0142yn\u0105\u0107 na dowolny serwer. I s\u0105 na to lepsze sposoby.<\/p>\n<h2>Prawid\u0142owa praca z \u017c\u0105daniami Ajax<\/h2>\n<p>Jak zwykle, poniewa\u017c WordPress jest dostarczany z jQuery, b\u0119d\u0119 go u\u017cywa\u0142; jednak zach\u0119cam r\u00f3wnie\u017c \u2013 je\u015bli jeszcze tego nie zrobi\u0142e\u015b \u2013 do spojrzenia na <strong><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Guide\/AJAX\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Ajax w ES6<\/a><\/strong>, aby dowiedzie\u0107 si\u0119, jak to zrobi\u0107 natywnie.<\/p>\n<p>W ka\u017cdym razie pomys\u0142 jest taki: zamiast ustawia\u0107 jaki\u015b interwa\u0142, u\u017cyj wbudowanych funkcji Ajax, aby w\u0142a\u015bciwie oceni\u0107 odpowied\u017a. I tylko w okre\u015blonych warunkach ponownie uruchom funkcj\u0119.<\/p>\n<p><a href=\"https:\/\/api.jquery.com\/jquery.post\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Przyk\u0142ad: metoda $.post<\/a> jQuery oferuje kilka funkcji, kt\u00f3rych mo\u017cna u\u017cy\u0107 w\u0142a\u015bnie do tego. Na przyk\u0142ad oferuje metody takie jak:<\/p>\n<ul>\n<li>Gotowe()<\/li>\n<li>ponie\u015b\u0107 pora\u017ck\u0119()<\/li>\n<li>zawsze()<\/li>\n<\/ul>\n<p>I ka\u017cdy z nich ma by\u0107 uruchamiany w okre\u015blonych warunkach, kt\u00f3re za chwil\u0119 poka\u017c\u0119 w niekt\u00f3rych przyk\u0142adach kodu.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164533-61e766ff924f1.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164533-61e766ff924f1.png\" alt=\"Prawid\u0142owa praca z \u017c\u0105daniami Ajax w WordPress\" ><\/a><\/p>\n<p>Jednak zanim to zrobisz, wa\u017cne jest, aby zrozumie\u0107, \u017ce wysy\u0142am kilka parametr\u00f3w, kt\u00f3re, jak zak\u0142adam, znasz:<\/p>\n<ul>\n<li>URL WordPress Ajax (kt\u00f3ry zdefiniuj\u0119 jako acme.ajax_url),<\/li>\n<li>adres URL do ogl\u0105danego posta (kt\u00f3ry b\u0119dzie przechowywany w zmiennej sUrl),<\/li>\n<li>i numer bezpiecze\u0144stwa, kt\u00f3ry b\u0119d\u0119 nazywa\u0142 acme.security<\/li>\n<\/ul>\n<p>Je\u015bli kt\u00f3rakolwiek z powy\u017cszych nie jest jasna, przeczytaj powi\u0105zane strony, aby zobaczy\u0107, jak to osi\u0105gn\u0105\u0107.<\/p>\n<p>Ale bior\u0105c to pod uwag\u0119, oto pomys\u0142, jak mo\u017cesz zarz\u0105dza\u0107 powtarzaj\u0105cymi si\u0119 odpowiedziami Ajax bez setInterval.<\/p>\n<h3>1 Funkcja dla pracy<\/h3>\n<p>Pierwsz\u0105 rzecz\u0105, kt\u00f3r\u0105 musisz zrobi\u0107, to otoczy\u0107 prac\u0119, kt\u00f3r\u0105 zamierzasz wykona\u0107, we w\u0142asnej funkcji. Oznacza to, \u017ce mo\u017cesz wywo\u0142a\u0107 go z dowolnego miejsca w aplikacji po stronie klienta lub nawet w kontek\u015bcie timera (je\u015bli jest to absolutnie konieczne).<\/p>\n<p><strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-00-initial-function-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Na przyk\u0142ad<\/a><\/strong> :<\/p>\n<pre><code>var _processArticle = function() {\n\n  var request =\n    $.post(acme.ajax_url, {\n      action:  'acme_get_data',\n      url:      sUrl\n      security: acme.security\n    }, function(response) {\n      \/\/ ...\n    })\n    .done(function(response) {\n      \/\/ ...\n    })\n    .fail(function(xhr, status, error) {\n      \/\/ ...\n    })\n    .always(function() {\n      \/\/ ..\n    });\n}\n<\/code><\/pre>\n<p>Jak wida\u0107, posun\u0105\u0142em si\u0119 do przodu i odci\u0105\u0142em niekt\u00f3re funkcje, o kt\u00f3rych wspomnia\u0142em powy\u017cej.<\/p>\n<h3>2 Zajmij si\u0119 sukcesem<\/h3>\n<p>W przypadku sukcesu mo\u017cesz u\u017cy\u0107 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-01-handle-success-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">funkcji anonimowej<\/a><\/strong> jako wywo\u0142ania zwrotnego dla funkcji <strong>$.post<\/strong>. Podstawowym argumentem, kt\u00f3rym powiniene\u015b si\u0119 zajmowa\u0107, jest argument <strong>odpowiedzi .<\/strong><\/p>\n<p>Zazwyczaj lubi\u0119, gdy moja odpowied\u017a ma atrybut <strong>sukcesu<\/strong> i atrybut <strong>niepowodzenia<\/strong>. U\u0142atwia to za\u0142atwienie sprawy, gdy odpowied\u017a ca\u0142kowicie si\u0119 powiod\u0142a, ale dane, kt\u00f3re wr\u00f3ci\u0142y z serwera, nie by\u0142y takie, jakich si\u0119 spodziewa\u0142em.<\/p>\n<pre><code>var _processArticle = function() {\n\n  var request =\n    $.post(acme.ajax_url, {\n      action:  'acme_get_data',\n      url:      sUrl\n      security: acme.security\n    }, function(response) {\n\n      \/\/ Abort all request operations.\n      if (false === response.success) {\n        request.abort();\n      }\n\n      \/\/ Handle the successful response by modifying the DOM.\n    })\n    .done(function(response) {\n      \/\/ ...\n    })\n    .fail(function(xhr, status, error) {\n      \/\/ ...\n    })\n    .always(function() {\n      \/\/ ...\n    });\n}\n<\/code><\/pre>\n<p>Niekoniecznie oznacza to, \u017ce nast\u0105pi\u0142a awaria. To po prostu oznacza, \u017ce \u200b\u200bto, czego szuka\u0142em, nie zosta\u0142o znalezione.<\/p>\n<h3>3 Zajmij si\u0119 niepowodzeniem<\/h3>\n<p>Z drugiej strony zdarzaj\u0105 si\u0119 chwile, w kt\u00f3rych co\u015b mo\u017ce <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-02-handle-failure-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">zawie\u015b\u0107<\/a><\/strong>. Dlaczego tak si\u0119 dzieje mo\u017ce by\u0107 z wielu powod\u00f3w i aby to w\u0142a\u015bciwie zrozumie\u0107, warto przyjrze\u0107 si\u0119 argumentom, jakie dostarcza callback, a mianowicie <strong>statusowi<\/strong> i <strong>b\u0142\u0119dowi<\/strong>.<\/p>\n<pre><code>var _processArticle = function() {\n\n  var request =\n    $.post(acme.ajax_url, {\n      action:  'acme_get_data',\n      url:      sUrl\n      security: acme.security\n    }, function(response) {\n\n      \/\/ Abort all request operations.\n      if (false === response.success) {\n        request.abort();\n      }\n\n      \/\/ Handle the successful response by modifying the DOM like flashing the first image.\n      $('img:first').fadeTo('fast', 0.5, function() {\n        $(this).fadeTo('fast', 1);\n      });\n    })\n    .done(function(response) {\n      \/\/ ...\n    })\n    .fail(function(xhr, status, error) {\n\n      console.log('There was a problem with contacting the API.');\n\n      console.log('The status was:');\n      console.log(status);\n\n      console.log('The error was:')\n      cosole.log(error);\n    })\n    .always(function() {\n      \/\/ ...\n    });\n}\n<\/code><\/pre>\n<p>Nie mog\u0119 poda\u0107 tutaj konkretnych przyk\u0142ad\u00f3w, poniewa\u017c ka\u017cde API jest inne; jednak zalecam przynajmniej wypisanie danych do konsoli, aby\u015b m\u00f3g\u0142 zrozumie\u0107, co si\u0119 dzieje i jak z wdzi\u0119kiem sobie z tym poradzi\u0107 na poziomie kodu.<\/p>\n<h3>4 Post\u0119puj w przypadku bezwarunkowego<\/h3>\n<p>W tym konkretnym przypadku ta funkcja uruchomi si\u0119 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-03-handle-always-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">niezale\u017cnie<\/a><\/strong> od tego, czy co\u015b si\u0119 powiod\u0142o, czy nie.<\/p>\n<pre><code>var _processArticle = function() {\n\n  var request =\n    $.post(acme.ajax_url, {\n      action:  'acme_get_data',\n      url:      sUrl\n      security: acme.security\n    }, function(response) {\n\n      \/\/ Abort all request operations.\n      if (false === response.success) {\n        request.abort();\n      }\n\n      \/\/ Handle the successful response by modifying the DOM like flashing the first image.\n      $('img:first').fadeTo('fast', 0.5, function() {\n        $(this).fadeTo('fast', 1);\n      });\n    })\n    .done(function(response) {\n      \/\/ ...\n    })\n    .fail(function(xhr, status, error) {\n\n      console.log('There was a problem with contacting the API.');\n\n      console.log('The status was:');\n      console.log(status);\n\n      console.log('The error was:')\n      console.log(error);\n    })\n    .always(function() {\n      \/\/ Regardless of what happens, this is where you can provide the user feedback.\n    });\n}\n<\/code><\/pre>\n<p>Ta funkcja nie jest czym\u015b, czego zawsze mo\u017cesz potrzebowa\u0107 (gra s\u0142\u00f3w nie jest przeznaczona), ale jest to solidna opcja do, powiedzmy, ukrywania paska post\u0119pu lub wy\u015bwietlania czego\u015b w interfejsie u\u017cytkownika. Mo\u017ce to da\u0107 u\u017cytkownikowi pewn\u0105 informacj\u0119 zwrotn\u0105, \u017ce \u017c\u0105danie zako\u0144czy\u0142o swoj\u0105 prac\u0119 (ponownie, niezale\u017cnie od niepowodzenia lub sukcesu).<\/p>\n<h3>5 Ponownie zajmij si\u0119 sukcesem<\/h3>\n<p>Wreszcie, metoda <strong>wykonania<\/strong> jest bardzo podobna do metody sukcesu, ale pomy\u015bl o niej jako o tym, \u017ce nale\u017cy j\u0105 wywo\u0142a\u0107 po raz drugi.<\/p>\n<p>Oznacza to, \u017ce po otrzymaniu odpowiedzi z serwera z argumentem <strong>odpowiedzi<\/strong>, ta sama rzecz zostanie uruchomiona ponownie, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-04-handle-success-again-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">gdy wszystko inne zostanie zako\u0144czone<\/a>.<\/p>\n<pre><code>var _processArticle = function() {\n\n  var request =\n    $.post(acme.ajax_url, {\n      action:  'acme_get_data',\n      url:      sUrl\n      security: acme.security\n    }, function(response) {\n\n      \/\/ Abort all request operations.\n      if (false === response.success) {\n        request.abort();\n      }\n\n      \/\/ Handle the successful response by modifying the DOM.\n    })\n    .done(function(response) {\n      \/\/ Display any additional changes you may want to make based on the respnse.\n    })\n    .fail(function(xhr, status, error) {\n\n      console.log('There was a problem with contacting the API.');\n\n      console.log('The status was:');\n      console.log(status);\n\n      console.log('The error was:')\n      console.log(error);\n    })\n    .always(function() {\n      \/\/ Regardless of what happens, this is where you can provide the user feedback.\n    });\n}\n<\/code><\/pre>\n<p>Daje ci to kolejn\u0105 szans\u0119 na zrobienie wszystkiego, co chcesz zrobi\u0107 z argumentem odpowiedzi jeszcze raz, zanim wszystko si\u0119 zako\u0144czy.<\/p>\n<p>Rzadko tego u\u017cywam, ale zdarza\u0142o si\u0119, \u017ce chcia\u0142em usun\u0105\u0107 element dopiero po tym, jak co\u015b zosta\u0142o zrobione, wszystkie inne operacje zosta\u0142y wykonane i odpowied\u017a si\u0119 powiod\u0142a.<\/p>\n<h2>Mo\u017ce nie potrzebujesz tego wszystkiego<\/h2>\n<p>Oczywi\u015bcie wi\u0119kszo\u015b\u0107 powy\u017cszego kodu jest przeznaczona tylko do demonstracji obs\u0142ugi \u017c\u0105da\u0144. Ale celem jest pokazanie, jak obs\u0142u\u017cy\u0107 wspomniane \u017c\u0105danie bez konieczno\u015bci ustawiania interwa\u0142\u00f3w dla \u017c\u0105da\u0144 stosowych. Zamiast tego korzystasz z istniej\u0105cych wcze\u015bniej funkcji, aby, powiedzmy, ponownie wywo\u0142a\u0107 funkcj\u0119, je\u015bli wyst\u0105pi b\u0142\u0105d.<\/p>\n<p>W ka\u017cdym razie dla niekt\u00f3rych mo\u017ce to by\u0107 przesada, ale dla innych, kt\u00f3rzy s\u0105 przyzwyczajeni do u\u017cywania <strong>setInterval<\/strong>, mo\u017ce to by\u0107 znacznie lepszy spos\u00f3b na zarz\u0105dzanie \u017c\u0105daniami Ajax, kt\u00f3re nie nak\u0142adaj\u0105 si\u0119 na stos i uruchamiaj\u0105 to samo \u017c\u0105danie do serwera, gdy odpowied\u017a ju\u017c zosta\u0142a zarz\u0105dzany.<\/p>\n<p>I ostatecznie to jest cel: Wydajny kod, kt\u00f3ry pobiera potrzebne informacje bez blokowania interfejsu API innej firmy lub przegl\u0105darki naszego u\u017cytkownika.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jak mo\u017cemy prawid\u0142owo pracowa\u0107 z \u017c\u0105daniami Ajax, aby nie kumulowa\u0107 zasob\u00f3w serwera.<\/p>\n","protected":false},"author":1,"featured_media":164534,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,919,732,845,866],"tags":[1169],"class_list":["post-229668","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-javascript-7","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229668","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=229668"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229668\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/164534"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=229668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=229668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=229668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}