Есть ли верный способ «уступить» в смысле кооперативных потоков в javascript? - PullRequest
6 голосов
/ 21 сентября 2009

Я пишу плагин ubiquity. Длинный обратный вызов функции для ajax-запроса блокирует поток GUI, вызывая блокировку firefox.

Очевидное решение, по-видимому, заключается в использовании некоторого вида отложенного выполнения (то есть мы хотим периодически добавлять выполнение, выполняющее этот запрос , в конец очереди событий, а затем разрешать другим командам быть выполненным.

Единственный способ, которым я могу думать об этом, - это использовать settimeout с таймаутом, равным нулю ... это гарантированно сработает или есть лучший способ сделать это.

Ответы [ 2 ]

7 голосов
/ 21 сентября 2009

Использование setTimeout с очень маленьким тайм-аутом (0 или почти нулевым, если вы чувствуете себя параноиком) - единственный способ сделать это в контексте браузера. Он работает очень хорошо и очень надежно, но не забывайте давать достаточно часто, но не слишком часто, так как требуется время, чтобы вернуться к вам ("некоторое время" в компьютерном смысле, конечно это почти мгновенно (по модулю другие вещи, которые вы, возможно, делаете) в человеческом смысле).

3 голосов
/ 21 сентября 2009

Убедитесь, что вы используете асинхронный запрос, так как синхронный запрос блокирует браузер (что объясняет блокировку графического интерфейса).

Если это не ваша проблема, я думаю, вы хотите что-то вроде этой очереди задач.

var queue = [];

queue.push(someTaskFunction);
queue.push(anotherTaskFunction);
// ...

var runQueue = (function () {
    var len = queue.length, task = 0;
    for (; task < len; task++) {
        yield queue[task]();
    }
}());

Позвоните runQueue.next(), чтобы выполнить следующее задание. Оберните его в оператор try..catch следующим образом:

try {
    runQueue.next();
} catch (e if (e instanceof StopIteration)) {}
...