4

Tengo una función, que usa webix.ajax( ) para realizar llamadas AJAX.

En webix, AJAX tiene la funcionalidad de no gestionar los timeout; no los considera un error, sino que los trata como si la llamada hubiera sido exitosa.

Para remediarlo, creé esta función:

function timedAjax( timeout, callback, method, url, args ) {
  if( 'call' in timeout ) {
    args = url;
    url = method;
    method = callback;
    callback = timeout;
    timeout = 10000;
  }

  if( args )
    ( webix.ajax( ).timeout( timeout )[method] )( url, args, { success: ResponseOk, error: ResponseError } );
  else
    ( webix.ajax( ).timeout( timeout )[method] )( url, undefined, { success: ResponseOk, error: ResponseError } );

  function ResponseError( text, data, xhr ) {
    var err;

    setTimeout( function( ) { callback( xhr.status === 0 ? true : false, text, data, xhr ) }, 0 );
  }

  function ResponseOk( text, data, xhr ) {
    setTimeout( function( ) { callback( false, text, data, xhr ); }, 0 );
  }
}

El código funciona correctamente; si no se pasa un argumento timeout, establece un valor por defecto de 10000ms, realiza la llamada a webix.ajax( ) correspondiente, y llama a la función callback con los argumentos correctos:

  • Si no hay error, la llama como

callback( false, text, data, xhr )

  • Si hay error, incluyendo timeout, la llama como

callback( true, text, data, xhr )

Ahora, estoy intentando modernizar ese código. He encontrado mucha documentación sobre como usar las promesas, pero no termino de aclararme al respecto.

webix tiene compatiblidad con Promises/A+. La propia llamada a webix.ajax( ) devuelve una promise con la funcionalidad indicada: si hay timeout, lo toma como reusultado exitoso.

¿ Como transformo el código anterior para que devuelva una promise ?

Trauma
  • 25,297
  • 4
  • 37
  • 60
  • 1
    Sugiero que mires [esta respuesta](https://es.stackoverflow.com/a/64863/29967), en el apartado que dice **Uso básico de las Promesas**. – A. Cedano May 02 '17 at 10:37
  • ¿La idea es que simplemente devuelva una [promise](https://docs.webix.com/api__ajax_post.html) (ver `Return value`) o que además devuelva los parámetros `error, text, data, xhr`? – Marcos May 02 '17 at 13:25

1 Answers1

2

Si es necesario que se continúe retornando los datos error, text, data, xhr, se me ocurre que podrías hacer lo siguiente:

  • Ya que vamos a devolver una promise, el parámetro callback habría que eliminarlo de la función timedAjax.
  • Deberiamos crear una promise utilizando el metodo webix.promise.defer
  • Luego dentro de las funciones ResponseOk y ResponseError, deberíamos resolver la promise. Nota: El método promise.resolve solo aceptar un parametro, por lo que es necesario devolver un objeto con toda la info.

Ejemplo:

function timedAjax(timeout, method, url, args) {
  var promise = webix.promise.defer();
  
  if (isNaN(timeout)) {
    args = url;
    url = method;
    method = timeout;
    timeout = 10000;
  }
  
  webix.ajax().timeout(timeout)[method](url, args || undefined, {
    success: ResponseOk,
    error: ResponseError
  });
  
  return promise;
  
  //
  
  function ResponseError(text, data, xhr) {
    // NOTA: No rejectamos la promesa porque estamos enviando `error=true|false`
    promise.resolve({
      error: xhr.status === 0 ? true : false, 
      text: text,
      data: data, 
      xhr: xhr
    });
  }

  function ResponseOk( text, data, xhr ) {
    promise.resolve({
      error: false, 
      text: text,
      data: data, 
      xhr: xhr
    });
  }
}

//////////////////
// EJEMPLO DE USO

timedAjax(3000, 'get', '//www.google.com')
  .then(function(res) {
    console.log(res);
  });
<script src="//cdn.webix.com/edge/webix.js" type="text/javascript"></script>
Marcos
  • 30,626
  • 6
  • 28
  • 63
  • Me has ahorrado responderte al comentario. Es **justo** lo que estaba buscando. Voy a probarlo. – Trauma May 02 '17 at 13:42