Tener este código:
const fs = require('fs') const file = 'books.json'; class Book{ constructor(code) { this._code = code; } get code() { return this._code; } set code(value) { this._code = value; } } async function writeBooks(){ const data = JSON.stringify([new Book('c1'), new Book('c2')]); await fs.promises.writeFile(file, data, 'utf8'); } async function getBook(code){ try{ const data = await fs.promises.readFile(file); const array = JSON.parse(data); return array.find(b => b.code === code); } catch (err){ console.log(err) } } writeBooks(); getBook('c1').then(b => console.log(b)); Me estoy volviendo undefined (en lugar del objeto de libro esperado).
Cómo obtener el objeto (el problema anterior)
Si la función async siempre devuelve la promesa, ¿cómo puedo devolver el objeto para el cliente, en lugar de que él tenga que llamar a then() desde getBook(code) ?
¿Debo await por fs.promises.writeFile() ? como lo estoy haciendo en writeBooks() ? Por lo que entiendo de async/await ahora, es que el valor de retorno de la función de await es el dato o el error. Pero dado que writeFile() no devuelve nada, o un error como máximo (a diferencia de readFile() ), ¿por qué querría await sin datos?
En realidad, la raíz del problema no se trata de async/awaits o de promesas. El problema es intentar escribir una matriz en un archivo json. Si escribe sus datos json como el fragmento de código a continuación (como un par clave-valor), su problema está resuelto.
{"1": [new Book('c1').code, new Book('c2').code]} //as a key-value pair const fs = require('fs') const file = 'books.json'; class Book{ constructor(code) { this._code = code; } get code() { return this._code; } set code(value) { this._code = value; } } async function writeBooks(){ const data = JSON.stringify({"1": [new Book('c1').code, new Book('c2').code]}); await fs.promises.writeFile(file, data, 'utf8'); } async function getBook(code){ try{ const data = await fs.promises.readFile(file); const dataOnJsonFile = JSON.parse(data); return dataOnJsonFile["1"]; } catch (err){ console.log(err) } } writeBooks(); getBook('c1').then(b => console.log(b));El problema anterior es que los Libros devueltos por JSON.parse solo tienen datos, no métodos, y por lo tanto no puedo obtener el code a través de get code(){} , sino solo como parámetro público de la clase Book como book._code , que sin embargo se rompe encapsulación (la convención es que _[propery] es privada, y debe haber getters/setters apropiados). Así que hice públicas las propiedades (y rompí la encapsulación), porque todavía no sé cómo asignar métodos a objetos creados a partir de JSON.
No, el resultado de async siempre es Promise. No puede desenvolverlo dentro de async , el cliente siempre tendrá que desenvolverlo. (así await fs.promises.WriteFile() lo desenvolverá, pero luego lo envolverá inmediatamente, antes de que regrese la función asíncrona.
como se explicó anteriormente.