Sé que javascript no usa Class , al menos no en el sentido común`. Me gustaría saber cómo devolver y guardar un valor de retorno de AJAX en una variable de clase en lugar de llamar a varios métodos dentro de la devolución de llamada.
var Reader = function(){ //Initialize some variables this.data = null; } Reader.prototype.makeAjaxCall = function(urlPath){ //Make and Ajax call and return some value Ajax.success(function(data){ this.data = data; }); } Reader.prototype.searchData = function(param){ //Needs access to this.data } Reader.prototype.findData = function(id){ //Needs access to this.data } Reader.prototype.deleteItem = function(id){ // Needs access to this.data } En el código anterior, cualquier función que necesite acceso a la propiedad de data debe llamarse dentro de la ajax success callback , por lo que si tengo diez métodos que necesitan datos, tendré que alinearlos todos dentro de la devolución de llamada, lo cual hago. no se siente bien. ¿Cómo minimizo la cantidad de funciones en la devolución de llamada y me aseguro de otras formas de que la función sea exitosa y los data se guarden en la variable de instancia?
La parte esencial es cómo manejar datos asíncronos con JavaScript. Hay algunas soluciones bien probadas para esto: funciones y promesas.
En ambos casos, el Lector debe tener un constructor que asigne los datos de esta manera:
function Reader(data) { this.data = data; }El enfoque de devolución de llamada requiere una función de fábrica, que tiene una devolución de llamada.
function getReader(url, callBack) { Ajax.success(function(data){ callBack( new Reader(data) ); }); }Y úsalo como
getReader(url, function(reader) { reader.searchData(); });El enfoque Promise no requiere una devolución de llamada inmediata, por lo que el resultado puede almacenarse en una variable y transmitirse como una variable, lo que tiene algunas ventajas:
function getReaderPromise(url) { return new Promise( function( resolve, reject ) { Ajax.success(function(data){ resolve( new Reader(data) ); }); }); }Sin embargo, usar la promesa generalmente requiere llamar a la función entonces de la promesa:
getReaderPromise(url).then( function(reader) { reader.searchData(); }); // Fat arrow syntax getReaderPromise(url).then( (reader) => { reader.searchData(); });En el futuro, puede deshacerse de las devoluciones de llamada con Promises usando generadores ES6 con un rendimiento como
let reader = yield getReaderPromise( url );Como se explica aquí: https://davidwalsh.name/async-generators
Podrías intentar algo como:
var Reader = function(){ //Initialize some variables this.data = null; } Reader.prototype.makeAjaxCall = function(urlPath){ //Make and Ajax call and return some value this.data = Ajax({url: urlPath}); // return promise } Reader.prototype.searchData = function(param){ //Needs access to this.data if(this.data){ this.data.then(...); } } Reader.prototype.findData = function(id){ //Needs access to this.data if(this.data){ this.data.then(...); } } Reader.prototype.deleteItem = function(id){ // Needs access to this.data if(this.data){ this.data.then(...); } }En tu código:
Reader.prototype.makeAjaxCall = function(urlPath){ //Make and Ajax call and return some value Ajax.success(function(data){ this.data = data; }); }"este" no es el contexto de la instancia de Reader, debe cambiarlo a
Reader.prototype.makeAjaxCall = function(urlPath){ var myThis = this; //Make and Ajax call and return some value Ajax.success(function(data){ myThis .data = data; }); }Para mantener el puntero a la instancia de Reader en la variable myThis y acceder dentro de la función de éxito