{"id":230327,"date":"2022-11-24T09:36:00","date_gmt":"2022-11-24T06:36:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230327"},"modified":"2022-11-09T21:09:51","modified_gmt":"2022-11-09T18:09:51","slug":"trabalhando-corretamente-com-solicitacoes-ajax-no-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/trabalhando-corretamente-com-solicitacoes-ajax-no-wordpress\/","title":{"rendered":"Trabalhando corretamente com solicita\u00e7\u00f5es Ajax no WordPress"},"content":{"rendered":"\n<p>Sempre que voc\u00ea est\u00e1 trabalhando com APIs de terceiros e est\u00e1 fazendo isso de forma ass\u00edncrona, sempre h\u00e1 a chance de que o que voc\u00ea est\u00e1 solicitando retorne um resultado indesejado.<\/p>\n<p>Talvez seja um c\u00f3digo de erro, talvez seja um aviso, ou talvez seja uma simples mensagem dizendo algo como &quot;Ainda estamos processando sua solicita\u00e7\u00e3o do nosso lado&quot;.<\/p>\n<p>Em cada caso, voc\u00ea geralmente pode lidar com eles no lado do servidor muito bem e deixar o lado do cliente saber como lidar com isso. Mas se voc\u00ea estiver lidando com o \u00faltimo caso, \u00e9 a\u00ed que voc\u00ea \u00e9 bloqueado pelo processamento de terceiros; h\u00e1 outras coisas que voc\u00ea pode fazer para lidar melhor com essa situa\u00e7\u00e3o.<\/p>\n<p>Por exemplo, neste \u00faltimo caso, \u00e9 melhor esperar um pouco e fazer a requisi\u00e7\u00e3o novamente para ver se a API tem uma resposta diferente para voc\u00ea.<\/p>\n<p>Mas ao fazer isso, requer Ajax, que obviamente requer JavaScript. Um dos m\u00e9todos \u00f3bvios, ainda mais datados, de fazer isso \u00e9 usar setInterval.<\/p>\n<p>O problema com isso, por\u00e9m, \u00e9 que ele cria uma pilha de solicita\u00e7\u00f5es e, assim que a resposta estiver pronta, cada item da pilha receber\u00e1 a mesma resposta.<\/p>\n<p>Isso pode afetar drasticamente qualquer servidor. E h\u00e1 maneiras melhores de fazer isso.<\/p>\n<h2>Trabalhando corretamente com solicita\u00e7\u00f5es Ajax<\/h2>\n<p>Como de costume, j\u00e1 que o WordPress vem com jQuery, vou usar isso; no entanto, tamb\u00e9m exorto voc\u00ea \u2013 se ainda n\u00e3o o fez \u2013 a olhar para o <strong><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Guide\/AJAX\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Ajax no ES6<\/a><\/strong> para ter uma ideia de como fazer isso nativamente.<\/p>\n<p>De qualquer forma, a ideia \u00e9 esta: em vez de configurar algum intervalo, use as fun\u00e7\u00f5es internas do Ajax para avaliar a resposta corretamente. E somente sob certas condi\u00e7\u00f5es, acione a fun\u00e7\u00e3o novamente.<\/p>\n<p>Caso em quest\u00e3o: o m\u00e9todo <a href=\"https:\/\/api.jquery.com\/jquery.post\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$.post<\/a> do jQuery oferece algumas fun\u00e7\u00f5es que podem ser usadas exatamente para isso. Por exemplo, oferece m\u00e9todos como:<\/p>\n<ul>\n<li>feito()<\/li>\n<li>falhou()<\/li>\n<li>sempre()<\/li>\n<\/ul>\n<p>E cada um deles deve ser executado sob certas condi\u00e7\u00f5es das quais mostrarei em alguns exemplos de c\u00f3digo momentaneamente.<\/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=\"Trabalhando corretamente com solicita\u00e7\u00f5es Ajax no WordPress\" ><\/a><\/p>\n<p>Antes de fazer isso, por\u00e9m, \u00e9 importante entender que existem v\u00e1rios par\u00e2metros que estou enviando com os quais suponho que voc\u00ea esteja familiarizado:<\/p>\n<ul>\n<li>o URL do WordPress Ajax (que definirei como acme.ajax_url),<\/li>\n<li>uma URL para a postagem que estamos visualizando (que ser\u00e1 armazenada em uma vari\u00e1vel sUrl),<\/li>\n<li>e um nonce de seguran\u00e7a que chamarei de acme.security<\/li>\n<\/ul>\n<p>Se algum dos itens acima n\u00e3o estiver claro, leia as p\u00e1ginas vinculadas para ver como isso \u00e9 alcan\u00e7ado.<\/p>\n<p>Mas com isso dito, aqui est\u00e1 a ideia por tr\u00e1s de como voc\u00ea pode gerenciar respostas repetidas do Ajax sem setInterval.<\/p>\n<h3>1 Uma Fun\u00e7\u00e3o para o Trabalho<\/h3>\n<p>A primeira coisa que voc\u00ea precisa fazer \u00e9 envolver o trabalho que voc\u00ea vai fazer em sua pr\u00f3pria fun\u00e7\u00e3o. Isso significa que voc\u00ea pode cham\u00e1-lo de qualquer outro lugar no aplicativo do lado do cliente ou at\u00e9 mesmo no contexto de um cron\u00f4metro (se absolutamente necess\u00e1rio).<\/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\">Por exemplo<\/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>E, como voc\u00ea pode ver, eu fui em frente e apaguei algumas das fun\u00e7\u00f5es que mencionei acima.<\/p>\n<h3>2 Lide com o sucesso<\/h3>\n<p>No caso de sucesso, voc\u00ea pode usar <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-01-handle-success-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">uma fun\u00e7\u00e3o an\u00f4nima<\/a><\/strong> como retorno de chamada para a fun\u00e7\u00e3o <strong>$.post<\/strong>. O argumento principal com o qual voc\u00ea deve se preocupar \u00e9 o argumento de <strong>resposta .<\/strong><\/p>\n<p>Normalmente, gosto que minhas respostas tenham um atributo de <strong>sucesso<\/strong> e um atributo de <strong>falha<\/strong>. Isso torna mais f\u00e1cil lidar com um caso sempre que a resposta for totalmente bem-sucedida, mas os dados que retornaram do servidor n\u00e3o foram o que eu esperava.<\/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>Isso n\u00e3o significa necessariamente que houve uma falha. Significa apenas que o que eu estava procurando recuperar n\u00e3o foi encontrado.<\/p>\n<h3>3 Lidar com a falha<\/h3>\n<p>Por outro lado, h\u00e1 momentos em que algo pode <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-02-handle-failure-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">falhar<\/a><\/strong>. Por que isso acontece pode ser por v\u00e1rios motivos e para entend\u00ea-lo corretamente, vale a pena inspecionar os argumentos que o retorno de chamada fornece, ou seja, o <strong>status<\/strong> e o <strong>erro<\/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>N\u00e3o posso dar exemplos concretos aqui porque cada API \u00e9 diferente; no entanto, recomendo pelo menos gravar dados no console para que voc\u00ea possa entender o que est\u00e1 acontecendo e como lidar com isso em um n\u00edvel de c\u00f3digo.<\/p>\n<h3>4 Lidar com o Caso Incondicional<\/h3>\n<p>Nesse caso espec\u00edfico, essa fun\u00e7\u00e3o ser\u00e1 acionada <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-03-handle-always-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">independentemente<\/a><\/strong> de algo ter sido bem-sucedido ou n\u00e3o.<\/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>Esta fun\u00e7\u00e3o n\u00e3o \u00e9 algo que voc\u00ea pode sempre precisar (sem trocadilhos), mas \u00e9 uma op\u00e7\u00e3o s\u00f3lida para, digamos, ocultar uma barra de progresso ou exibir algo na interface do usu\u00e1rio. Isso pode dar ao usu\u00e1rio um feedback de que a solicita\u00e7\u00e3o concluiu seu trabalho (novamente, independentemente de falha ou sucesso).<\/p>\n<h3>5 Lide com o sucesso, novamente<\/h3>\n<p>Finalmente, o m\u00e9todo <strong>done<\/strong> \u00e9 muito parecido com o m\u00e9todo de sucesso, mas pense nele como destinado a ser chamado uma segunda vez.<\/p>\n<p>Isso significa que depois que a resposta voltar do servidor com o argumento de <strong>resposta, a mesma coisa ser\u00e1 acionada novamente<\/strong> <a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-04-handle-success-again-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">quando todo o resto for conclu\u00eddo<\/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>Isso lhe d\u00e1 outra chance de fazer o que quiser com o argumento de resposta mais uma vez antes que tudo seja conclu\u00eddo.<\/p>\n<p>Eu raramente uso isso, mas houve momentos em que eu quis remover um elemento somente depois que algo foi feito, todos os outros processamentos foram feitos e a resposta foi bem-sucedida.<\/p>\n<h2>Talvez voc\u00ea n\u00e3o precise de tudo<\/h2>\n<p>Obviamente, grande parte do c\u00f3digo acima \u00e9 apenas para uma demonstra\u00e7\u00e3o de como lidar com solicita\u00e7\u00f5es. Mas o objetivo \u00e9 mostrar como lidar com a requisi\u00e7\u00e3o sem a necessidade de definir intervalos para empilhar as requisi\u00e7\u00f5es. Em vez disso, voc\u00ea aproveita as fun\u00e7\u00f5es pr\u00e9-existentes para, digamos, chamar a fun\u00e7\u00e3o novamente se houver um erro.<\/p>\n<p>De qualquer forma, isso pode ser um exagero para alguns, mas para outros que est\u00e3o acostumados a usar <strong>setInterval<\/strong>, pode ser uma maneira muito melhor de gerenciar solicita\u00e7\u00f5es Ajax que n\u00e3o se acumulam e disparar a mesma solicita\u00e7\u00e3o para o servidor quando uma resposta j\u00e1 foi gerenciou.<\/p>\n<p>E, em \u00faltima an\u00e1lise, esse \u00e9 o objetivo: c\u00f3digo eficiente que recupera as informa\u00e7\u00f5es de que precisamos sem sobrecarregar a API de terceiros ou o navegador do nosso pr\u00f3prio usu\u00e1rio.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como podemos trabalhar adequadamente com solicita\u00e7\u00f5es Ajax para n\u00e3o acumular recursos do servidor.<\/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":[722,733,920,846,867],"tags":[1170],"class_list":["post-230327","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","category-javascript-8","category-outro","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=230327"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230327\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/164534"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}