Estoy usando OpenLayers para dibujar un mapa de Ordnance Survey del Reino Unido. Tengo ejemplos de trabajo, pero usan un método menos seguro para acceder a los servidores UKOS al proporcionar una clave en la URL, mientras que me gustaría usar el arreglo OAuth2 más seguro. Con este fin, ya tengo un script CGI que consulta a los servidores para obtener un token de sesión y lo devuelve como JSON. El problema es hacer que la página de dibujo del mapa ESPERE su regreso, de la siguiente manera:
UKOS.getToken = async function () { if ( !UKOS.token || new Date().getTime() > UKOS.token.issued_at + 1000 * (UKOS.token.expires_in - 15) ) UKOS.token = await fetch(/* CGI Script */).then((response) => response.json() ); console.log(UKOS.token.access_token); return UKOS.token.access_token; }; // ... fetch(UKOS.WMTS + "&request=GetCapabilities&version=2.0.0", { headers: { Authorization: "Bearer " + UKOS.getToken() }, }).then(/* etc */);He leído que el uso explícito de 'async' y 'await' no debería ser necesario cuando se usa 'fetch', pero su uso definitivamente altera el comportamiento, aunque ninguna de las versiones funciona, de la siguiente manera:
Con 'async' y 'await' como arriba:
Los mensajes de error provienen del token de acceso que se devolvió como 'indefinido' antes de que el script CGI pudiera devolverlo, pero después de esto, la instrucción console.log, que esperó el token, imprime la respuesta correcta.
Sin estas palabras clave:
El archivo console.log imprime indefinido antes de los mensajes de error que resultan del valor de retorno indefinido.
Esto se está probando con FF 96.0.3, pero PaleMoon 29.4.4.4 hace lo mismo, IE muere mucho antes, sospecho porque no comprende la sintaxis de secuencias de comandos modernas.
¿Cómo puedo forzar la devolución a esperar el valor correcto?
Las funciones async siempre devuelven promesas. Entonces, un código como { Authorization: "Bearer " + UKOS.getToken() } intentará concatenar una cadena con una promesa, que no es lo que desea. Debe llamar a .then en la promesa y poner su código en la devolución de llamada:
UKOS.getToken() .then(token => { return fetch(UKOS.WMTS + "&request=GetCapabilities&version=2.0.0", { headers: { Authorization: "Bearer " + token }, }) }) .then(/* etc */) O necesita poner su código en una función async y await la promesa:
async function someFunction() { const token = await UKOS.getToken(); const response = await fetch(UKOS.WMTS + "&request=GetCapabilities&version=2.0.0", { headers: { Authorization: "Bearer " + token }, }) /* etc */ }