es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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});
});

Tags:  , , , ,

Answer

  1. Avatar for 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 porque map devuelve una matriz de promesas cuando se return 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ón return en la devolución de llamada de map para que se devuelva el resultado de la consulta de knex y pueda ser resuelta por el método Promise.all().

    Aquí está el código actualizado:

    const getAllByDistance = (location) =>
      knex('companies')
        .select()
        .then((entries) =>
          Promise.all(
            entries.map((company) =>
              getDistance(location, `${company.street}, ${company.postcode} ${company.place}`).then(
                (distance) => {
                  return 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);
        });
    };
    

    Al envolver los resultados de la devolución de llamada de map con Promise.all(), la función ahora esperará a que todas las promesas de la matriz se resuelvan antes de devolver el resultado final.

Comments are closed.