Tengo una función de controlador para el evento de drop que se parece a esto:
da.addEventListener("drop", function(e) { e.stopPropagation(); var xhr = new XMLHttpRequest(); ... (configure XMLHttpRequest) var fd = new FormData(); [...e.dataTransfer.items].forEach(it => { it.getAsString(value => { console.log(`append ${it.type} ${value}`); fd.append(`${it.type}`, value); }); }); console.log("send"); xhr.send(fd); }); El problema aquí es que send() ocurre antes fd.append() , porque it.getAsString() parece ser asíncrono.
Después de leer algunos artículos sobre devoluciones de llamada, funciones asincrónicas, promesas, etc. Traté de agregarlo en un bloque .then() :
it.getAsString(value => { return value; }).then(value => { console.log(`append ${it.type} ${value}`); fd.append(`${it.type}`, value); }); Esperaba tener problemas con el value que no se propaga correctamente, pero en cambio obtuve
Uncaught TypeError: it.getAsString(...) is undefined E incluso el depurador integrado subraya getAsString .
¿Qué estoy haciendo aquí? ¿Por qué parece que getAsString está definido cuando lo uso sin .then(value => {}) pero funciona correctamente sin .then() ?
En un nivel más abstracto, ¿cómo agregaría correctamente items de un DataTransferItem a una instancia de FormData antes de enviarlo?
Actualizar
Combinar la iteración a través .items y luego usar .getData() funciona para mí, pero no se siente bien.
[...e.dataTransfer.items].forEach(it => { fd.append(`${it.type}`, e.dataTransfer.getData(it.type)); });