{"id":229985,"date":"2022-11-24T09:13:00","date_gmt":"2022-11-24T06:13:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229985"},"modified":"2022-11-09T19:34:54","modified_gmt":"2022-11-09T16:34:54","slug":"trabajar-correctamente-con-solicitudes-ajax-en-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/trabajar-correctamente-con-solicitudes-ajax-en-wordpress\/","title":{"rendered":"Trabajar correctamente con solicitudes Ajax en WordPress"},"content":{"rendered":"\n<p>Siempre que trabaje con API de terceros, y lo haga de forma as\u00edncrona, siempre existe la posibilidad de que lo que sea que est\u00e9 solicitando devuelva un resultado no deseado.<\/p>\n<p>Tal vez sea un c\u00f3digo de error, tal vez sea una advertencia, o tal vez sea un mensaje simple que dice algo como &quot;Todav\u00eda estamos procesando su solicitud por nuestra parte&quot;.<\/p>\n<p>En cada caso, generalmente puede manejarlos bien en el lado del servidor y dejar que el lado del cliente sepa c\u00f3mo manejarlo. Pero si est\u00e1 lidiando con el \u00faltimo caso, ah\u00ed es donde est\u00e1 bloqueado por el procesamiento de terceros; hay otras cosas que puede hacer para manejar mejor esta situaci\u00f3n.<\/p>\n<p>Por ejemplo, en el \u00faltimo caso, es mejor esperar un poco y luego volver a realizar la solicitud para ver si la API tiene una respuesta diferente para usted.<\/p>\n<p>Pero al hacer esto, requiere Ajax que obviamente requiere JavaScript. Uno de los m\u00e9todos obvios, aunque m\u00e1s anticuados, para hacer esto es usar setInterval.<\/p>\n<p>Sin embargo, el problema con esto es que crea una pila de solicitudes y luego, cuando la respuesta est\u00e1 lista, cada elemento de la pila obtendr\u00e1 la misma respuesta.<\/p>\n<p>Esto puede afectar dr\u00e1sticamente a cualquier servidor dado. Y hay mejores maneras de hacer esto.<\/p>\n<h2>Trabajar correctamente con solicitudes Ajax<\/h2>\n<p>Como de costumbre, dado que WordPress viene con jQuery, lo usar\u00e9; sin embargo, tambi\u00e9n lo insto, si a\u00fan no lo ha hecho, a mirar <strong><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Guide\/AJAX\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Ajax en ES6<\/a><\/strong> para tener una idea de c\u00f3mo hacer esto de forma nativa.<\/p>\n<p>De todos modos, la idea es esta: en lugar de configurar un intervalo, utilice las funciones integradas de Ajax para evaluar la respuesta correctamente. Y solo bajo ciertas condiciones, active la funci\u00f3n nuevamente.<\/p>\n<p>Caso en cuesti\u00f3n: el m\u00e9todo <a href=\"https:\/\/api.jquery.com\/jquery.post\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$.post<\/a> de jQuery ofrece algunas funciones que se pueden usar exactamente para esto. Por ejemplo, ofrece m\u00e9todos como:<\/p>\n<ul>\n<li>hecho()<\/li>\n<li>fallar()<\/li>\n<li>siempre()<\/li>\n<\/ul>\n<p>Y cada uno de estos est\u00e1 destinado a ejecutarse bajo ciertas condiciones, de las cuales mostrar\u00e9 en algunos ejemplos de c\u00f3digo moment\u00e1neamente.<\/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=\"Trabajar correctamente con solicitudes Ajax en WordPress\" ><\/a><\/p>\n<p>Sin embargo, antes de hacer eso, es importante comprender que hay varios par\u00e1metros que estoy enviando y que asumo te resultar\u00e1n familiares:<\/p>\n<ul>\n<li>la URL de WordPress Ajax (que definir\u00e9 como acme.ajax_url),<\/li>\n<li>una URL a la publicaci\u00f3n que estamos viendo (que se almacenar\u00e1 en una variable sUrl),<\/li>\n<li>y un nonce de seguridad al que llamar\u00e9 acme.security<\/li>\n<\/ul>\n<p>Si algo de lo anterior no est\u00e1 claro, lea las p\u00e1ginas vinculadas para ver c\u00f3mo se logra.<\/p>\n<p>Pero dicho esto, esta es la idea detr\u00e1s de c\u00f3mo puede administrar las respuestas repetidas de Ajax sin setInterval.<\/p>\n<h3>1 Una funci\u00f3n para el trabajo<\/h3>\n<p>Lo primero que debe hacer es envolver el trabajo que va a realizar en su propia funci\u00f3n. Esto significa que puede llamarlo desde cualquier otro lugar en la aplicaci\u00f3n del lado del cliente o incluso dentro del contexto de un temporizador (si es absolutamente necesario).<\/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 ejemplo<\/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>Y, como puede ver, segu\u00ed adelante y elimin\u00e9 algunas de las funciones que mencion\u00e9 anteriormente.<\/p>\n<h3>2 Manejar el \u00e9xito<\/h3>\n<p>En caso de \u00e9xito, puede utilizar <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-01-handle-success-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">una funci\u00f3n an\u00f3nima<\/a><\/strong> como devoluci\u00f3n de llamada para la funci\u00f3n <strong>$.post<\/strong>. El argumento principal con el que debe preocuparse es el argumento de <strong>respuesta .<\/strong><\/p>\n<p>Por lo general, me gusta que mis respuestas tengan un atributo de <strong>\u00e9xito<\/strong> y un atributo de <strong>fracaso<\/strong>. Esto hace que sea m\u00e1s f\u00e1cil manejar un caso siempre que la respuesta sea completamente exitosa, pero los datos que regresaron del servidor no fueron los que esperaba.<\/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>Esto no significa necesariamente que hubo una falla. Simplemente significa que lo que sea que estaba buscando recuperar no fue encontrado.<\/p>\n<h3>3 Manejar la falla<\/h3>\n<p>Por otro lado, hay momentos en los que algo puede <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-02-handle-failure-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fallar<\/a><\/strong>. La raz\u00f3n por la que sucede esto puede deberse a varias razones y, para comprenderlo correctamente, vale la pena inspeccionar los argumentos que proporciona la devoluci\u00f3n de llamada, es decir, el <strong>estado<\/strong> y el <strong>error<\/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>No puedo dar ejemplos concretos aqu\u00ed porque cada API es diferente; sin embargo, recomiendo al menos escribir datos en la consola para que pueda comprender lo que est\u00e1 sucediendo y c\u00f3mo puede manejarlo correctamente a nivel de c\u00f3digo.<\/p>\n<h3>4 Manejar el Caso Incondicional<\/h3>\n<p>En este caso particular, esta funci\u00f3n se activar\u00e1 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-03-handle-always-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">independientemente<\/a><\/strong> de si algo tuvo \u00e9xito o no.<\/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 funci\u00f3n no es algo que siempre pueda necesitar (sin juego de palabras), pero es una opci\u00f3n s\u00f3lida para, por ejemplo, ocultar una barra de progreso o mostrar algo en la interfaz de usuario. Esto puede brindarle al usuario un poco de informaci\u00f3n de que la solicitud ha completado su trabajo (nuevamente, independientemente de la falla o el \u00e9xito).<\/p>\n<h3>5 Manejar el \u00e9xito, otra vez<\/h3>\n<p>Finalmente, el m\u00e9todo <strong>done<\/strong> es muy parecido al m\u00e9todo success, pero piense que est\u00e1 destinado a ser llamado por segunda vez.<\/p>\n<p>Eso significa que despu\u00e9s de que la respuesta haya regresado del servidor con el argumento de <strong>respuesta<\/strong>, lo mismo volver\u00e1 a activarse una <a href=\"https:\/\/gist.github.com\/tommcfarlin\/2dbe93fe47a96657e2ce7e4da0313bab#file-04-handle-success-again-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">vez que todo lo dem\u00e1s se haya completado<\/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>Esto le da otra oportunidad de hacer lo que quiera con el argumento de respuesta una vez m\u00e1s antes de que todo se haya completado.<\/p>\n<p>Raramente uso esto, pero ha habido momentos en los que he querido eliminar un elemento solo despu\u00e9s de que se hizo algo, se realiz\u00f3 todo el otro procesamiento y la respuesta fue exitosa.<\/p>\n<h2>Tal vez no lo necesites todo<\/h2>\n<p>Obviamente, gran parte del c\u00f3digo anterior es solo para una demostraci\u00f3n sobre c\u00f3mo manejar las solicitudes. Pero el prop\u00f3sito es mostrar c\u00f3mo manejar dicha solicitud sin necesidad de establecer intervalos para apilar solicitudes. En su lugar, aprovecha las funciones preexistentes para, por ejemplo, volver a llamar a la funci\u00f3n si hay un error.<\/p>\n<p>De todos modos, esto puede ser excesivo para algunos, pero para otros que est\u00e1n acostumbrados a usar <strong>setInterval<\/strong>, puede ser una forma mucho mejor de administrar las solicitudes de Ajax que no se acumulan y enviar la misma solicitud al servidor cuando ya se ha recibido una respuesta. administrado.<\/p>\n<p>Y, en \u00faltima instancia, ese es el objetivo: c\u00f3digo eficiente que recupera la informaci\u00f3n que necesitamos sin atascar la API de terceros o el navegador de nuestro propio usuario.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>C\u00f3mo podemos trabajar correctamente con las solicitudes de Ajax para no acumular recursos del 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":[716,727,914,840,861],"tags":[1172],"class_list":["post-229985","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","category-javascript-2","category-otro","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=229985"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229985\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/164534"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=229985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=229985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=229985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}