【发布时间】:2017-11-14 05:59:33
【问题描述】:
所以我正在做一些promise 链,因为我需要一些同步运行的代码。在我有两个嵌套的forEach 之前一切都很好。在第一个forEach 之后,我显示了具有我要迭代的下一个数组的实际对象。在那儿!但是后来我尝试迭代那个数组并且是undefined?
vm.enviarEmail = function() {
var result = {};
var def = $q.defer();
def.promise
.then(function(result){
console.log("1");
return estacion.leerEstacionesInforiego()
.then(function(respuesta) {
angular.forEach(respuesta, function(est) {
est.latitud = $rootScope.dmsToddI(est.latitud);
est.longitud = $rootScope.dmsToddI(est.longitud);
});
result.estaciones = respuesta;
console.log("estaciones",result.estaciones);
return result;
}, function(respuesta) {
console.log("ERROR: obtención de las estaciones no realizada");
});
return result;
})
.then(function(result) {
console.log("2");
return user.leerUsuarios()
.then(function(respuesta) {
result.users = respuesta;
console.log("usuarios",result.users);
return result;
}, function(respuesta) {
console.log("ERROR: obtención de usuarios no realizada.");
});
return result;
})
.then(function(result) {
console.log("3");
angular.forEach(result.users, function(user) {
user.html = "<style>td {border:solid 1px;}</style><table><thead><tr><th>Parcela</th><th>Estación</th><th>Cultivo</th><th>Método de riego</th>"+
"<th>Fecha siembra</th><th>Fecha último riego</th><th>Recomendación</th></tr></thead><tbody>";
campo.leerParcelasPropietario(user.id)
.then(function(respuesta) {
user.parcelas = respuesta;
}, function(respuesta) {
console.log("ERROR: obtención de parcelas por usuario no realizada.");
});
});
console.log("parcelas",result);
return result;
})
.then(function(result) {
console.log("4");
angular.forEach(result.users, function(user) {
console.log(user,user.parcelas);
angular.forEach(user.parcelas, function(par) {
console.log("parcela",par.nombre);
var hoy = new Date(); // Fecha actual
// Obtener el cultivo de la parcela
campo.leerCultivo(par.cultivo)
.then(function(respuesta) {
par.cultivo = respuesta;
console.log(par);
}, function(respuesta) {
console.log("ERROR: obtención del cultivo no realizada");
});
// Obtener el método de riego de la parcela
campo.leerMetodoRiego(par.riego)
.then(function(respuesta) {
par.riego = respuesta;
}, function(respuesta) {
console.log("ERROR: obtención del método de riego no realizada");
});
// Calcular la estación cercana
var distMin = 99999999;
var x1 = new google.maps.LatLng(par.latitud,par.longitud);
angular.forEach(result.estaciones, function(est) {
var x2 = new google.maps.LatLng(est.latitud,est.longitud);
var distancia = google.maps.geometry.spherical.computeDistanceBetween(x1, x2);
if (distancia < distMin) {
distMin = distancia;
par.estacion = est;
}
});
// Cálculo de días desde el último riego
var fecha = new Date(Date.parse(par.consulta));
par.diasR = (hoy - fecha)/(1000*60*60*24); // En días y no milisegundos
// Cálculo del estado del cultivo
var fechaS = new Date(Date.parse(par.siembra));
par.diasE = (hoy - fechaS)/(1000*60*60*24);
if (par.diasE < 46)
par.estado = 'ini';
else if (par.diasE < 76)
par.estado = 'des';
else if (par.diasE < 96)
par.estado = 'med';
else
par.estado = 'fin';
});
});
return result;
})
.then(function(result) {
console.log("5");
angular.forEach(result.users, function(user) {
console.log("para obtener datos",result.users);
angular.forEach(user.parcelas, function(par) {
estacion.obtenerDatosInforiego(Math.round(par.diasR),par.estacion.indicativo,par.estacion.provincia)
.then(function(respuesta) {
par.datos = respuesta;
}, function(respuesta) {
console.log("ERROR: obtención de los datos de Inforiego no realizada");
});
});
});
return result;
})
.then(function(result) {
console.log("6");
angular.forEach(result.users, function(user) {
angular.forEach(user.parcelas, function(par) {
par.datos_totales = {et0: 0, etc: 0, pe: 0}; // Los datos totales obtenidos de los cálculos
angular.forEach(par.datos, function(diadatos) {
// Corrección de la temperatura media
diadatos.tempmedia = (diadatos.tempmax+diadatos.tempmin)/2;
// Cálculo de la presión atmosférica (kPa)
diadatos.presion = 101.3*Math.pow(((293-(0.0065*par.estacion.altitud))/293),5.26);
// Cálculo de la constante psicométrica (kPa/ºC)
diadatos.constante_psicometrica = diadatos.presion*0.000665;
// Cálculo de la presión de saturación de vapor a la temperatura del aire (max, med y min) (kPa)
var psvmax = 0.6108*Math.pow(2.7183,(17.27*diadatos.tempmax)/(diadatos.tempmax+237.3));
var psvmin = 0.6108*Math.pow(2.7183,(17.27*diadatos.tempmin)/(diadatos.tempmin+237.3));
var psvmed = (psvmax+psvmin)/2;
// Cálculo de la presión real de vapor (kPa)
diadatos.presion_real_vapor = (psvmed*diadatos.humedadmedia)/100;
// Cálculo de la pendiente de la curva de presión de vapor (kPa/ºC)
diadatos.pendiente_curva_presion = (4098*psvmed)/Math.pow((diadatos.tempmedia+237.3),2);
// Cálculo de la ET0
diadatos.et0 = ((0.408*diadatos.pendiente_curva_presion*diadatos.rn)
+(diadatos.constante_psicometrica*diadatos.velviento*900*(psvmed-diadatos.presion_real_vapor))/(273+diadatos.tempmedia))
/(diadatos.pendiente_curva_presion+(diadatos.constante_psicometrica*(1+0.34*diadatos.velviento)));
// Cálculo de la ETc
if (par.estado == 'ini') {
diadatos.etc = diadatos.et0*par.cultivo.coef_ini;
diadatos.kc = par.cultivo.coef_ini;
} else if (par.estado == 'des') {
diadatos.etc = diadatos.et0*par.cultivo.coef_des;
diadatos.kc = par.cultivo.coef_des;
} else if (par.estado == 'med') {
diadatos.etc = diadatos.et0*par.cultivo.coef_med;
diadatos.kc = par.cultivo.coef_med;
} else if (par.estado == 'fin') {
diadatos.etc = diadatos.et0*par.cultivo.coef_fin;
diadatos.kc = par.cultivo.coef_fin;
}
// Sumar para los totales
par.datos_totales.et0 = par.datos_totales.et0 + diadatos.et0;
par.datos_totales.etc = par.datos_totales.etc + diadatos.etc;
par.datos_totales.pe = par.datos_totales.pe + diadatos.pepmon;
});
par.datos_totales.rr = (par.datos_totales.etc-par.datos_totales.pe)/par.riego.coef_eficiencia;
user.html = user.html + "<tr><td>" + par.nombre + "</td><td>" + par.estacion.nombre + "</td>"+
"<td>" + par.cultivo.nombre + "</td><td>" + par.riego.nombre + "</td>"+
"<td>" + $filter('date')(par.siembra, 'dd-MM-yyyy') + "</td>"+
"<td>" + $filter('date')(par.consulta, 'dd-MM-yyyy') + "</td>"+
"<td><b>" + Math.round(par.datos_totales.rr) + "</b> l/m<sup>2</sup></td></tr>";
});
});
return result;
})
.then(function(result) {
console.log("7");
angular.forEach(result.users, function(user) {
if (user.usuario != 'jlmm') {
user.html = user.html + "</tbody></table><br><a href='http://localhost:8080/AgriWea/#!/'>AgriWea</a>";
$http.post('http://localhost:8100/sendmail', {params: {
from: 'AgriWea <jmariscan@dominio.es>',
to: user.email,
subject: 'Recomendación diaria de riego',
html: user.html}})
.then(function(respuesta) {
console.log("Email enviado correctamente",texto);
}, function(respuesta) {
console.log("Email no enviado", respuesta);
});
}
});
})
.catch(function (error) {
console.log(error);
});
def.resolve(result);
如您所见,我有一个console.log,这就是我得到的:
我在想也许对象是 undefined 因为 Angular 中的异步但在同一个 console.log 我可以看到该数组存在但如果我尝试访问它是 undefined。救命!
解决方案
使用@trincot 的代码,我减少了then 的数量,并且只用了三个代码。谢谢大家!
【问题讨论】:
-
您是否在另一个
then(..)s 中为result.users分配了任何东西?剩下的可以分享一下吗? -
尝试将
debugger;放入 forEach 并逐步查看会发生什么 -
作为一个提示,我可以告诉你我和你的情况一样,但是控制台日志欺骗了我,这确实是异步设置值晚于访问代码的问题。我认为控制台日志是在您的循环之后执行的,尽管在您的代码中它是之前编写的。请检查您的回调并确保之前的每个回调都成功。
-
@NikolajDamLarsen 里面有函数的所有代码..太多了呵呵。
标签: javascript arrays angularjs promise