#javascript #jquery #asynchronous #settimeout #q
#javascript #jquery #асинхронный #settimeout #q
Вопрос:
Рабочий код: в Chrome, Firefox
let sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
};
И где-то в моей функции я использую async,await, чтобы сделать задержку синхронной
function updateHandler(newTags, tagName, contentIds) {
let deferred = Q.defer(),
counter = 0,
failedIDS = [],
data = {};
data["contentIds"] = contentIds;
data["failedIDS"] = failedIDS;
if (contentIds.length === 0) {
return Promise.resolve(data);
}
//aync and await is here
_.forEach(contentIds, async function (contentId) {
//wait for some time and continue
await sleep(150);
let tags = [], activity;
//API hits..
osapi.jive.core.get({
v: "v3",
href: "/contents/" contentId ""
}).execute(function (content) {
tags = content.tags;
activity = content["updated"];
content["tags"] = _.union(tags, newTags);
osapi.jive.core.put({
v: "v3",
href: "/contents/" contentId "",
body: content,
"minor": "true",
"updated": activity
}).execute(function (response) {
counter ;
if (response.error) {
failedIDS.push(contentId);
}
if (counter === contentIds.length) {
deferred.resolve(data);
}
}, function (error) {
counter ;
failedIDS.push(contentId);
if (counter === contentIds.length) {
deferred.resolve(data);
}
}
);
})
});
return deferred.promise;
};
Таким образом, для того, чтобы этот API-интерфейс заработал и обновил все элементы, необходимо 0,15 секунды.
Поскольку async и await не будут работать в IE, я хотел написать базовую wait(ms)
функцию, которая ожидает 0,15 секунды.
Примечание: Итак, без sleep()
функции приведенный выше цикл отлично работает для первой итерации и завершается сбоем для второй итерации и завершает выполнение кода. ТАКИМ образом, для каждой итерации требуется задержка в 0,15 секунды, это ограничение продукта.
setTimeout()
является асинхронным.. поэтому я его не использовал.
Приведенный ниже код работает для меня.. Но это не то, чего я хочу, потому что браузеру не хватает памяти и больше загрузка процессора, дорого..
function wait(ms) {
console.log("started............");
var start = Date.now(),
now = start;
while (now - start < ms) {
now = Date.now();
}
console.log("finished............");
}
Вопрос: Я хочу иметь задержку не менее 0,15 секунды для каждой итерации, как я могу этого добиться.
Я попробовал следующий способ, изображение здесь. Успешно обновляет только от 16 до 19 содержимого из 100 повторяющихся элементов, а затем выдает то же самое, error
что и без sleep()
функции.
Комментарии:
1. Почему бы просто не использовать setTimeout с вашим дальнейшим кодом в обратном вызове?
2. Я пробовал это, если повторяющиеся элементы равны 100, то он обновляется для диапазона от 16 до 19, а затем выдает ту же ошибку (которую я получал при запуске без
sleep()
)3. Как насчет определения массива с вашими элементами, а затем установки таймаута для функции, в которой первый элемент будет передан вашему api. После этого функция установит для себя еще один тайм-аут
4. @gopigorantala Вы можете прочитать эту статью mozilla
5. Вы пробовали рекурсивный setTimeout? Это должно гарантировать задержку между каждым последующим запросом
Ответ №1:
Допустим, мне нужно запускать эту функцию запроса каждые 150 мс:
const request = () => new Promise(res => setTimeout(() => { console.log('done'); res() }, 1000))
//
Затем я могу использовать setTimeout
рекурсивно для добавления задержки между каждым запросом:
let counter = 0;
// this handler will be passed into a setTimeout
// to kick off the whole thing
const handler = () => {
console.log(counter);
// request api thing
request().then(() => {
counter ;
if (counter === 100) return;
setTimeout(handler, 150) // remove this
})
}
// kick off
setTimeout(handler, 150)
Это гарантирует, что каждый запрос завершен, прежде чем ожидать запуска следующего.
Комментарии:
1. У меня есть рекурсивный вызов функции, например:
updateHandler(a,b,c).then(...)
и вthen()
я проверяю, есть ли failedIds .. и если они!=0
, то вызываю тот же рекурсивный fn. Позвольте мне попробовать ваш подход в рамках итерации и выполнить обещание..2. Спасибо .. это решение сработало для меня .. хотя мне нужно сделать обещание совместимым с IE
3.
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script>
добавление этого заставило обещание сработать как по волшебству..4. рад, что это помогает. В прошлом мне приходилось разрабатывать для ie11 несколько раз и заполнять. ввод-вывод — это божья милость!
5. поскольку каждый
promise
разрешен.. Я установил время ожидания равным 0 вместо 150 миллионов .. это более оптимизировано с точки зрения производительности.. будьте осторожны, установка 0 также добавляет некоторую задержкуsetTimeout
на 16-20 миллиметров.. ссылка: цикл обработки событий (потрясающе объяснено ..) .. посмотрите это видео до конца, станет понятнее, как цикл обработки событий работает в однопоточной среде (JS).