Почему новый модуль JavaScript запрос является синхронным? Предполагается ли, что он используется только в очереди заданий?
Есть ли способ сделать асинхронные запросы http (s) в ArangoDB?
Почему новый модуль JavaScript запрос является синхронным? Предполагается ли, что он используется только в очереди заданий?
Есть ли способ сделать асинхронные запросы http (s) в ArangoDB?
Полное раскрытие: я являюсь частью команды разработчиков ArangoDB и в основном работаю над Foxx и всем JavaScript. Я также написал модуль org/arangodb/request
.
ArangoDB — это среда, отличная от Node.js, несмотря на то, что у них много общего (например, использование движка JavaScript V8). В отличие от Node.js (или браузера), ArangoDB использует модель параллелизма на основе потоков и не имеет цикла событий. Однако потоки не отображаются в JavaScript (и фактически в V8 каждый поток полностью изолирован), поэтому обычно вам даже не нужно думать о них.
В браузере и в Node.js такие функции, как setTimeout
, работают, задерживая выполнение кода через цикл событий (пока не пройдет определенное время или пока не произойдет внешнее событие).
В ArangoDB код всегда выполняется линейно. Например, входящие HTTP-запросы передаются контроллерам Foxx в JavaScript, и ответ отправляется, как только контроллер возвращается. Даже если бы вы могли использовать setTimeout
, внешние ресурсы, с которыми вы работали (или даже «внутренние» ресурсы, такие как коллекции документов и транзакции), вероятно, уже исчезли бы к тому времени, когда отложенный код мог бы выполняться.
Из-за этого функция request
, предоставляемая модулем org/arangodb/request
, также полностью синхронна. Вместо возврата промиса или обратного вызова он напрямую возвращает входящие данные ответа. Это также явно не тот же модуль, что и request
в npm, а скорее синхронная реализация, основанная на API этого модуля в той мере, в какой реализация его API возможна вне Node.js (например, без включения потоков и возврата удаленный ответ вместо приема обратных вызовов).
Если вы работали с Node.js/io.js, это может показаться неправильным, потому что неблокирующий ввод-вывод может обеспечить более высокую пропускную способность, но имейте в виду, что цели разработки ArangoDB и Node.js очень разные. Node.js построен на потоках и сетевых подключениях. ArangoDB построена как постоянное хранилище данных и вместо этого должна иметь дело с транзакциями и блокировками.
Вероятно, не самая лучшая идея обращаться к внешним API напрямую с ваших контроллеров Foxx, если у вас высока вероятность серьезной сетевой задержки или если ответ внешнего API не важен для ответа клиента. Для этого и нужны очереди Foxx. Ярким примером этого являются транзакционные электронные письма.
Хотя Foxx очень универсален, его основное внимание уделяется тому, чтобы позволить вам перемещать большую часть вашего приложения (особенно логику, которая выигрывает от приближения к данным) непосредственно в базу данных. Для проектов малого и среднего масштаба вы, вероятно, можете обойтись без внешних вызовов API. Но если ваше приложение в первую очередь связано с общением с другими службами по сети, выполнение этого кода в базе данных, вероятно, не является оптимальным решением.
К счастью, ArangoDB хорошо сочетается с другими, поэтому легко переместить ваш ресурсоемкий сетевой код из Foxx, если вы обнаружите, что он становится узким местом в производительности при более высоких нагрузках. Foxx не устраняет необходимость в серверах приложений, но может значительно уменьшить их сложность.
В качестве исправления к ответу Брайана: к сожалению, обещания также не позволят вам писать асинхронный код в синхронной среде. В Promises/A+ spec обещания должны выполняться асинхронно. Там, где они изначально не поддерживаются, их все равно нужно создавать поверх существующих функций, таких как setTimeout
или process.nextTick
, ни одна из которых не реализована в ArangoDB.