¿Por qué mi función está devolviendo una Promesa { } en lugar de mis entradas?
Problema:
Quiero obtener las compañías dentro de un rango específico (en km) desde una ubicación determinada.
Estas compañías están almacenadas en una base de datos que actualmente contiene 2 registros para pruebas.
Entre otras cosas, también uso la API de matriz de distancias de Google para calcular la distancia.
Después de que no funcionara, una depuración me mostró que la función devuelve [Promise {<pending>}, Promise {<pending>}]
.
Código:
const
axios = require("axios"),
knex = require('knex')(require('../knexfile'));
const getAllByDistance = (location) =>
knex('companies')
.select()
.then(entries =>
entries.map(company =>
getDistance(location, `${company.street}, ${company.postcode} ${company.place}`)
.then(distance => {
knex('companies')
.select()
.where(parseInt(company.maximum_distance_km) >= parseInt(distance.toString().slice(0, -3)))
}))
);
const getDistance = async (loc1, loc2) => {
const origins = encodeURI(`?origins=${loc1}`);
const destinations = encodeURI(`&destinations=${loc2}`);
const key = `&key=${process.env.VUE_APP_GOOGLE_MAPS_API_KEY}`;
const config = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/distancematrix/json${origins}${destinations}${key}`,
headers: {}
};
return await axios(config)
.then((response) => {
return response.data['rows'][0]['elements'][0]['distance'].value;
})
.catch((err) => {
console.log(err);
});
}
Llamada a la función con depuración:
companyService
.getByDistance(location)
.then(companies => {
console.log(companies)
res.status(200);
res.json(companies);
})
.catch(err => {
res.status(500);
res.end(Error: ${err.message}
);
});
davy.ai
Solución:
El problema es que la función
getAllByDistance
está devolviendo una matriz de promesas sin resolver (es decir,[Promise {<pendiente>}, Promise {<pendiente>}]
). Esto ocurre porquemap
devuelve una matriz de promesas cuando sereturn
una promesa desde la función de devolución de llamada.Para solucionar este problema, debemos utilizar el método
Promise.all()
para esperar a que todas las promesas se resuelvan antes de devolver el resultado final. También debemos agregar una declaraciónreturn
en la devolución de llamada demap
para que se devuelva el resultado de la consulta deknex
y pueda ser resuelta por el métodoPromise.all()
.Aquí está el código actualizado:
Al envolver los resultados de la devolución de llamada de
map
conPromise.all()
, la función ahora esperará a que todas las promesas de la matriz se resuelvan antes de devolver el resultado final.