Как вы обрабатываете несколько запросов GET с помощью Node + Express [дубликат]

Вы можете получить один элемент, запустив

document.querySelector('.myElement').style.size = '100px';

, но он будет работать для первого элемента с классом .myElement.

Если вы хотите применить это для всех элементы с классом я предлагаю вам использовать

document.querySelectorAll('.myElement').forEach(function(element) {
    element.style.size = '100px';
});
77
задан codersarepeople 4 April 2012 в 03:20
поделиться

6 ответов

Вы не очень конкретно относитесь к своему коду, поэтому я создам сценарий. Допустим, у вас 10 вызовов ajax, и вы хотите аккумулировать результаты этих 10 аякс-звонков, а затем, когда они все закончили, вы хотите что-то сделать. Вы можете сделать это так, аккумулируя данные в массиве и отслеживая, когда последний закончен:

Ручной счетчик

var ajaxCallsRemaining = 10;
var returnedData = [];

for (var i = 0; i < 10; i++) {
    doAjax(whatever, function(response) {
        // success handler from the ajax call

        // save response
        returnedData.push(response);

        // see if we're done with the last ajax call
        --ajaxCallsRemaining;
        if (ajaxCallsRemaining <= 0) {
            // all data is here now
            // look through the returnedData and do whatever processing 
            // you want on it right here
        }
    });
}

Примечание: здесь важна обработка ошибок (не показано, потому что это зависит от того, как вы делаете свои айакс-звонки). Вам нужно подумать о том, как вы собираетесь справляться с ситуацией, когда один вызов ajax никогда не завершается, либо с ошибкой, либо застрял в течение длительного времени или времени после долгого времени.


jQuery Promises

Добавление к моему ответу в 2014 году. В наши дни обещания часто используются для решения этой проблемы, поскольку jQuery $.ajax() уже возвращает обещание, а $.when() сообщит вам, когда группа обещаний все решены и собирают результаты возврата для вас:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
    // returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
    // you can process it here
}, function() {
    // error occurred
});

Стандартные обещания ES6

Как указано в ответе kba : если у вас есть среда с встроенными встроенными обещаниями (современный браузер или node.js или с использованием babeljs, перетаскивающими или использующими обещание polyfill), тогда вы можете использовать обещания, указанные в ES6. См. эту таблицу для поддержки браузера. Обещания поддерживаются практически во всех текущих браузерах, кроме IE.

Если doAjax() возвращает обещание, вы можете сделать это:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});

Если вам нужно чтобы выполнить обезврежденную асинхронную операцию в ту, которая возвращает обещание, вы можете «обещать» это следующим образом:

function doAjax(...) {
    return new Promise(function(resolve, reject) {
        someAsyncOperation(..., function(err, result) {
            if (err) return reject(err);
            resolve(result);
        });
    });
}

И затем используйте шаблон выше:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});
< hr>

Bluebird Promises

Если вы используете библиотеку с большим количеством функций, такую ​​как библиотека обещаний Bluebird , тогда у нее есть некоторые дополнительные функции, чтобы сделать это проще:

 var doAjax = Promise.promisify(someAsync);
 var someData = [...]
 Promise.map(someData, doAjax).then(function(results) {
     // all ajax results here
 }, function(err) {
     // some error here
 });
160
ответ дан Community 22 August 2018 в 23:19
поделиться
  • 1
    Решение jQuery работает очень хорошо для меня! – larrydahooster 23 September 2015 в 12:31
  • 2
    @kba - я бы точно не назвал этот ответ устаревшим, поскольку все методы все еще применимы, особенно если вы уже используете jQuery для Ajax. Но я обновил его несколькими способами, чтобы включить собственные обещания. – jfriend00 19 November 2015 в 23:04
  • 3
    в эти дни существует гораздо более чистое решение, которое даже не нуждается в jquery. Я делаю это с API-интерфейсом Fetch и обещаниями – philx_x 14 April 2016 в 19:20
  • 4
    @philx_x - Что вы делаете с поддержкой IE и Safari? – jfriend00 14 April 2016 в 20:37
  • 5
    @ jfriend00 github сделал полиполк github.com/github/fetch . Или я не уверен, что babel поддерживает выборку. babeljs.io – philx_x 14 April 2016 в 20:43

Вы можете эмулировать его следующим образом:

  countDownLatch = {
     count: 0,
     check: function() {
         this.count--;
         if (this.count == 0) this.calculate();
     },
     calculate: function() {...}
  };

, тогда каждый асинхронный вызов выполняет следующее:

countDownLatch.count++;

, в то время как в каждом асинхронном обратном вызове в конце метода вы добавьте эту строку:

countDownLatch.check();

Другими словами, вы эмулируете функцию обратного отсчета.

7
ответ дан Eugene Retunsky 22 August 2018 в 23:19
поделиться
  • 1
    В 99% всех случаев использования Promise - это путь, но мне нравится этот ответ, потому что он иллюстрирует метод управления кодом Async в ситуациях, когда многозадачность Promise больше, чем JS, который его использует! – Sukima 5 September 2016 в 13:46

Регистрация с 2015 года. Теперь у нас есть native promises в последнем браузере (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 и Android-браузер 4.4 .4 и iOS Safari 8.4, но не Internet Explorer, Opera Mini и более старые версии Android.

Если мы хотим выполнить 10 асинхронных действий и получить уведомление, когда они все закончили, мы можем использовать native Promise.all , без каких-либо внешних библиотек:

function asyncAction(i) {
    return new Promise(function(resolve, reject) {
        var result = calculateResult();
        if (result.hasError()) {
            return reject(result.error);
        }
        return resolve(result);
    });
}

var promises = [];
for (var i=0; i < 10; i++) {
    promises.push(asyncAction(i));
}

Promise.all(promises).then(function AcceptHandler(results) {
    handleResults(results),
}, function ErrorHandler(error) {
    handleError(error);
});
12
ответ дан kba 22 August 2018 в 23:19
поделиться

Вы можете использовать jQuery Отложенный объект вместе с методом , когда .

deferredArray = [];
forloop {
    deferred = new $.Deferred();
    ajaxCall(function() {
      deferred.resolve();
    }
    deferredArray.push(deferred);
}

$.when(deferredArray, function() {
  //this code is called after all the ajax calls are done
});
10
ответ дан Paul 22 August 2018 в 23:19
поделиться
  • 1
    Вопрос не был помечен для jQuery, который обычно означает, что OP не хочет отвечать на jQuery. – jfriend00 4 April 2012 в 03:21
  • 2
    @ jfriend00 Я не хотел изобретать велосипед, когда он уже был создан в jQuery – Paul 4 April 2012 в 03:23
  • 3
    @Paul, так что вместо этого заново создайте колесо, в которое вы включили 40kb мусора, чтобы сделать что-то простое (отложенное) – Raynos 4 April 2012 в 03:26
  • 4
    Но не все могут или хотят использовать jQuery, и пользовательский здесь на SO - это то, что вы указываете, что помечаете ли вы свой вопрос с помощью jQuery или нет. – jfriend00 4 April 2012 в 03:26
  • 5
    Ошибка $ .when в этом примере неверна. Чтобы подождать массив отложенных / обещаний, вам нужно использовать $ .when.apply ($, обещает). Then (function () {/ * do stuff * /}). – danw 19 April 2013 в 23:12

Это, по-моему, самый опрятный способ.

Promise.all

FetchAPI

(по какой-то причине Array.map не работает внутри. Затем функции для меня. Но вы можете использовать .forEach и [] .concat () или что-то подобное)

Promise.all([
  fetch('/user/4'),
  fetch('/user/5'),
  fetch('/user/6'),
  fetch('/user/7'),
  fetch('/user/8')
]).then(responses => {
  return responses.map(response => {response.json()})
}).then((values) => {
  console.log(values);
})
3
ответ дан philx_x 22 August 2018 в 23:19
поделиться
  • 1
    Я думаю, что это должно быть return responses.map(response => { return response.json(); }) или return responses.map(response => response.json()). – user 27 June 2016 в 04:41

Используйте библиотеку потока управления, например after

after.map(array, function (value, done) {
    // do something async
    setTimeout(function () {
        // do something with the value
        done(null, value * 2)
    }, 10)
}, function (err, mappedArray) {
    // all done, continue here
    console.log(mappedArray)
})
1
ответ дан Raynos 22 August 2018 в 23:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: