Experimental support for 'Top-Level Await' just landed in Node.js core and Chrome Dev Tools, and Safari Web Inspector!
Да да, в Node.js 14.3 уже есть возможность писать верхнеуровневые await , пока, правда, в экспериментальном режиме. А так же еще одна особенность: они доступны только в ESM модулях иначе не сработают. Если вы пользуетесь Babel, то вы можете уже использовать в продакшене эту фичу. Так же top level await были добавлены в TypeScript 3.8 еще в Феврале 2020 года. Так же эта возможность давно доступна в проекте Deno.
Помимо Node.js эта фича языка доступан в Chrome Dev Tools и Safari Web Inspector.
let data = (await fetch('https://geekjob.ru/vacancies?format=json')).data;
console.log(data);
Но все же, если хочется использовать эту фичу в ноде нативно без транспайлеров, то вам нужно будет запуститься с флагами. Без флагов получится такой вариант - old way.
// index.msj
await Promise.resolve(console.log('🎉'));
// → SyntaxError: await is only valid in async function
void async function() {
await Promise.resolve(console.log('🎉'));
// → 🎉
}();
И если вы запустите проект с включенными опциями, то результат будет ок в обоих случаях.
node --experimental-top-level-await --harmony-top-level-await index.mjs
В чем собственно суть проблемы?
В JS много асинхронного кода, особенно если мы работаем с библиотеками баз данных. Node.js это не только среда для серверных веб-приложений, но так же можно писать разные вспомогательные скрипты, где асинхронность избыточна.
Типичный кейс работы с базой данных в Express:
async routeFunction(req, res, next) {
let db = await dbConnect();
let result = await db.query('...');
if (result.some) {
...
}
else {
...
}
next();
}
Если же этот участок переписывать через промисы или еще хуже через колбэки, то код станет менее читаемым и более сложным.
С новым подходом в данном случае просто уйдет слово async и функции можно будет делать более универсальными.
Второй кейс - это необходимая синхронность, когда происходит подключение разных библиотек, но эта фича будет полезна в браузерах, когда туда завезут top level await'ы. Например:
var jQuery;
try {
jQuery = await import('https://ajax.googleapis.com/libs/jquery.js');
} catch {
jQuery = await import('/local/jquery.js');
}
С учетом разных блокировок, связанных с политикой, теперь такой код все более актуальнее, правда сейчас он реализуется все еще таким образом:
<script src="//ajax.googleapis.com/libs/jquery/jquery.js"></script>
<script>window.jQuery || document.write('<script src="/local/jquery.js">\x3C/script>')</script>
Если интересна тема, больше подробностей на странице предложения: