Если мне нужно вызвать 3 http API в последовательном порядке, что было бы лучшей альтернативой следующему коду:
http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) {
res.on('data', function(d) {
});
});
}
});
});
}
});
});
}
node.js
synchronization
Говард
источник
источник
sync-request
библиотеки, который является хорошим ответом на заголовок этого вопроса, но не является ответом на то, что подразумевает код вопроса. Ответ ниже о обещаниях - лучший ответ на это. Что вы имели в виду?Ответы:
Использование отложенных файлов вроде
Futures
.Если вам нужно передать область видимости, просто сделайте что-то вроде этого
источник
Мне тоже нравится решение Raynos, но я предпочитаю другую библиотеку управления потоком.
https://github.com/caolan/async
В зависимости от того, нужны ли вам результаты в каждой последующей функции, я бы использовал серию, параллель или водопад.
Серии, когда они должны выполняться последовательно, но вам не обязательно нужны результаты при каждом последующем вызове функции.
Параллельно, если они могут выполняться параллельно, вам не нужны результаты каждой из них во время каждой параллельной функции, и вам нужен обратный вызов, когда все они будут завершены.
Waterfall, если вы хотите преобразовать результаты в каждой функции и перейти к следующей
источник
Вы можете сделать это с помощью моей библиотеки Common Node :
источник
require(...).HttpClient is not a constructor
запрос синхронизации
Безусловно, самый простой, который я нашел и использовал, - это запрос синхронизации, и он поддерживает как узел, так и браузер!
Вот и все, без сумасшедшей конфигурации, без сложной установки библиотеки, хотя у нее есть резервная версия библиотеки. Просто работает. Я пробовал здесь другие примеры и был озадачен, когда нужно было выполнить много дополнительных настроек или установки не работали!
Ноты:
Пример, который использует sync-request, не очень хорош, когда вы его используете
res.getBody()
, все, что делает get body, - это принимает кодировку и преобразует данные ответа. Просто сделайres.body.toString(encoding)
вместо этого.источник
Я бы использовал рекурсивную функцию со списком API
изменить: запросить версию
изменить: запрос / асинхронная версия
источник
Кажется, решения этой проблемы бесконечны, вот еще одно :)
http://alexeypetrushin.github.com/synchronize
источник
Другая возможность - настроить обратный вызов, который отслеживает выполненные задачи:
Затем просто назначьте идентификатор каждому, и вы можете настроить свои требования, для которых задачи должны быть выполнены перед закрытием соединения.
Ладно, это некрасиво. Это еще один способ делать последовательные звонки. К сожалению, NodeJS не предоставляет самые простые синхронные вызовы. Но я понимаю, в чем приманка асинхронности.
источник
используйте последовательность.
sudo npm установить sequenty
или
https://github.com/AndyShin/sequenty
очень просто.
также вы можете использовать такой цикл:
источник
Использование библиотеки запросов может помочь свести к минимуму беспорядок:
Но для максимального удовольствия вы должны попробовать какую-нибудь библиотеку управления потоком, такую как Step - она также позволит вам распараллеливать запросы, если это приемлемо:
источник
Начиная с 2018 года, используя модули и обещания ES6, мы можем написать такую функцию:
а затем в другом модуле
Код должен выполняться в асинхронном контексте (с использованием
async
ключевого слова)источник
Существует множество библиотек потока управления - мне нравится consq (... потому что я его написал). Кроме того, он
on('data')
может запускаться несколько раз, поэтому используйте библиотеку-оболочку REST, например restler .источник
На это хорошо ответил Райнос. Однако с момента публикации ответа в библиотеке последовательностей произошли изменения.
Чтобы заставить последовательность работать, перейдите по этой ссылке: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
Вот как вы можете заставить его работать после
npm install sequence
:источник
Вот моя версия @andy-shin последовательно с аргументами в массиве вместо индекса:
источник
... 4 года спустя ...
Вот оригинальное решение с фреймворком Danf (вам не нужен код для такого рода вещей, только некоторая конфигурация):
Если вы хотите быть еще короче, вы можете использовать процесс сбора:
Взгляните на обзор платформы для получения дополнительной информации.
источник
Я попал сюда, потому что мне нужно было ограничить скорость http.request (~ 10 тыс. Запросов агрегирования для эластичного поиска для создания аналитического отчета). Следующее просто душило мою машину.
Мои URL-адреса очень просты, поэтому это может не тривиально относиться к исходному вопросу, но я думаю, что это потенциально применимо и стоит написать здесь для читателей, которые попадают сюда с проблемами, похожими на мои, и которым нужно тривиальное решение без библиотеки JavaScript.
Моя работа не зависела от заказа, и мой первый подход к этому заключался в том, чтобы обернуть его в сценарий оболочки, чтобы разбить его (потому что я новичок в JavaScript). Это было функционально, но неудовлетворительно. В конечном итоге мое решение JavaScript заключалось в следующем:
Похоже на взаимную рекурсию между collect и get_top . Я не уверен, что это действует, потому что система асинхронна, а функция collect завершается обратным вызовом, сохраненным для события в on. ('End' .
Я думаю, что это достаточно общий вопрос, чтобы применить его к исходному вопросу. Если, как в моем сценарии, последовательность / набор известны, все URL-адреса / ключи могут быть помещены в стек за один шаг. Если они рассчитываются по ходу выполнения, функция on ('end' может поместить следующий URL-адрес в стек непосредственно перед get_top () . Во всяком случае, результат имеет меньшую вложенность и может быть легче рефакторинг, когда API, который вы вызываете изменения.
Я понимаю, что это фактически эквивалентно простой рекурсивной версии @ generalhenry, приведенной выше (так что я поддержал это!)
источник
Супер запрос
Это еще один синхронный модуль, который основан на запросе и использует обещания. Супер простой в использовании, хорошо работает с тестами мокко.
npm install super-request
источник
Этот код можно использовать для синхронного и последовательного выполнения массива обещаний, после чего вы можете выполнить свой последний код в
.then()
вызове.источник
Я получил именно то, что вы (и я) хотели, без использования await, обещаний или включения какой-либо (внешней) библиотеки (кроме нашей собственной).
Вот как это сделать:
Мы собираемся создать модуль C ++ для работы с node.js, и эта функция модуля C ++ будет выполнять HTTP-запрос и возвращать данные в виде строки, и вы можете использовать это напрямую, выполнив:
ВЫ ГОТОВЫ приступить к работе?
Шаг 1: создайте новую папку где-нибудь еще на вашем компьютере, мы используем эту папку только для создания файла module.node (скомпилированного из C ++), вы можете переместить его позже.
В новой папке (я поместил свою в mynewFolder / src для упорядоченности):
затем
Теперь создайте 2 новых файла: 1 с именем something.cpp и поместите в него этот код (или измените его, если хотите):
Теперь создайте новый файл в том же каталоге с именем
something.gyp
и поместите в него (что-то вроде) это:Теперь в файле package.json добавьте:
"gypfile": true,
Теперь: в консоли,
node-gyp rebuild
Если он проходит через всю команду и говорит "ОК" в конце без ошибок, вам (почти) хорошо, если нет, оставьте комментарий.
Но если это сработает, перейдите в build / Release / cobypp.node (или как там он вам нужен), скопируйте его в свою основную папку node.js, а затем в node.js:
источник