Tengo una aplicación Angular con una simple llamada a un servicio para cargar una imagen en AWS S3. El servicio de carga debe devolver la respuesta de AWS a la persona que llama. A pesar de que el servicio de carga cargó con éxito el archivo y envió el mensaje de éxito a la consola, y a pesar de que se resolvió un RETORNO de la promesa, la persona que llama "entonces" no se activa. No hay mensaje de error, solo se muestra la siguiente instrucción console.log ignorado:
console.log('aws file returned: ', res);Aquí está la persona que llama:
this.aws.uploadDataFile(data).then(res => { if (res) { console.log('aws file returned: ', res); } }, err => { console.log('error: ', err); });Aquí está el servicio de carga llamado:
uploadDataFile(data: any){ const contentType = data.type; const bucket = new S3({ accessKeyId: environment.awsAccessKey, secretAccessKey: environment.awsSecret, region: environment.awsRegion }); const params = { Bucket: environment.awsBucket, Key: data.name, //manipulate filename here before uploading Body: data.value, ContentEncoding: 'base64', ContentType: contentType }; return new Promise(function(resolve,reject){ bucket.putObject(params, function(err, res) { if (err) { console.log(err); console.log('Error uploading data: ', res); return Promise.resolve(err); } console.log('succesfully uploaded the image! ' + JSON.stringify(res)); return Promise.resolve(res); }); }) }Veo el mensaje de éxito del servicio en la consola:
console.log('succesfully uploaded the image! ' + JSON.stringify(res));Pero este mensaje no se muestra:
console.log('aws file returned: ', res);Necesito el valor devuelto en la persona que llama para realizar más tareas. ¿Qué me estoy perdiendo?
La Promise que está creando tiene una devolución de llamada del executor que proporciona los métodos de resolve y reject que debe usar para resolver la promesa. Además, se ignora cualquier valor de retorno de su executor . No puede encadenarse a la promesa devolviendo una promesa en el executor . Esto está documentado en MDN para el constructor Promise .
El problema principal es que no está utilizando los parámetros del executor para resolver o rechazar la promesa. Esto deja su promesa en un estado pendiente por tiempo indefinido. Invocar la resolve o el reject adecuados solucionará el problema.
function uploadDataFile(data) { //... return new Promise(function(resolve, reject) { bucket.putObject(params, function(err, res) { if (err) { console.log(err); console.log('Error uploading data: ', res); reject(err); } else { console.log('succesfully uploaded the image! ' + JSON.stringify(res)); resolve(res); } }); }); } En su caso, está utilizando la API de AWS . Entonces, podría usar el método de promise integrado de AWS . El método de promise hace la misma conversión que el anterior.
function uploadDataFile(data) { //... return bucket.putObject(params).promise().then(function(res) { console.log('succesfully uploaded the image! ' + JSON.stringify(res)); return res; }).catch(function(err) { console.log('Error uploading data: '); console.log(err); throw err; }); }Si no necesita el registro adicional, simplemente puede devolver la promesa.
function uploadDataFile(data) { //... return bucket.putObject(params).promise(); }Estás resolviendo la promesa equivocada .
Promise.resolve es una función que crea una nueva promesa y la resuelve inmediatamente. Es extremadamente raro que sea realmente útil.
No es lo mismo que la función que pasa la función constructora de Promise a su devolución de llamada y se coloca en el primer argumento que ha llamado resolve .
Necesitas resolver esa promesa y no una nueva.
Tenga en cuenta que la API de AWS tiene soporte incorporado para promesas , por lo que no necesita prometer la función de devolución de llamada usted mismo de todos modos.