Tengo este fragmento de código que llama a una función getTableData y espera una Promesa a cambio.
function populateTableRows(url) { successCallback = () => { ... }; errorCallback = () => { ... }; getTableData(url, successCallback, errorCallback).then(tableData => { // do stuff with tableData } } Esto se usa en muchos lugares en mi base de código, y estoy buscando mantener el mismo comportamiento a medida que dejo de usar ajax de jQuery (y jQuery en general)
En getTableData, actualmente estoy usando $.ajax así
function getTableData(url, successCallback, errorCallback) { successCallback = successCallback || function() {}; errorCallback = errorCallback || function() {}; const ajaxOptions = { type: 'POST', url: url, dataType: 'json', xhrFields: { withCredentials: true }, crossDomain: true, data: { // some data } }; return $.ajax(ajaxOptions).done(successCallback).fail(errorCallback); } Esto actualmente devuelve una Promesa para solicitudes exitosas. Para solicitudes incorrectas donde se invoca el fail , no parece que se devuelva una Promesa y then no se ejecuta en la función de llamada (lo cual está bien en este caso).
Al convertir la solicitud para usar fetch, tengo algo como esto
function getTableData(url, successCallback, errorCallback) { successCallback = successCallback || function() {}; errorCallback = errorCallback || function() {}; return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, credentials: 'include', body: { // some data } }) .then(response => { let json = response.json(); if (response.status >= 200 && response.status < 300) { successCallback(json); return json; } else { return json.then(error => {throw error;}); } }).catch((error) => { errorCallback(error); return }); Las solicitudes exitosas parecen comportarse de manera similar al código ajax que tengo actualmente, pero ahora la devolución de llamada then está ejecutando para solicitudes incorrectas que están causando errores en mi código.
¿Hay alguna manera de fetch el comportamiento fail de jQuery donde aparentemente se aborta la Promesa por solicitudes incorrectas? Soy bastante nuevo en el uso de Promises y después de experimentar/buscar no he podido encontrar una solución.
Cuando .catch() en una cadena de promesas, significa que ya manejó el error y las llamadas subsiguientes .then() continúan con éxito.
Por ejemplo:
apiCall() .catch((error) => { console.log(error); return true; // error handled, returning true here means the promise chain can continue }) .then(() => { console.log('still executing if the API call fails'); }); Lo que desea, en su caso, es que cuando maneje el error con la devolución de llamada, continúe arrojándolo para que se rompa la cadena de promesa. La cadena necesita además un nuevo bloque .catch() para manejar el nuevo error.
apiCall() .catch((error) => { console.log(error); // "handled", but we're still not done throw error; // instead of returning true, we throw the error further // 👆 this can also be written as `return Promise.reject(error);` }) .then(() => { console.log('not executing anymore if the API call fails'); }) .catch((error) => { // handle the same error we have thrown from the previous catch block return true; // not throwing anymore, so error is handled }) .then(() => { console.log('always executing, since we returned true in the last catch block'); });Por cierto, lo que devuelves de un bloque then/catch, el siguiente lo obtendrá como parámetro.
apiCall() .then((response) => { /* do something with response */; return 1; }) .catch((error) => { return 'a'; }) .then((x) => console.log(x)) // x is 'a' if there's an error in the API call, or `1` otherwiseEn su .catch , implícitamente devuelve indefinido y, por lo tanto, "maneja" el error. El resultado es una nueva Promesa que cumple al undefined .
.catch((error) => { errorCallback(error); return Promise.reject(); });debería ser suficiente para mantener el rechazo de la Promesa devuelta.
O asigna la Promesa intermedia a una var y la devuelve, y no el resultado del manejo fallido:
var reqPromise = fetch(url, { // ... }) .then(response => { // ... return json.then(error => {throw error;}); }); reqPromise.catch((error) => { errorCallback(error); return }); return reqPromise;