Вызов асинхронных функций с большим количеством асинхронных функций внутри - PullRequest
0 голосов
/ 07 июня 2018

У меня возникают проблемы при попытке вызвать цепочку асинхронных функций внутри массива.Когда я вызываю функцию по отдельности, она работает без проблем, как в примере ниже:

function consoleAll(string) {
    return new Promise(function (resolve) {
        console1(string).then(function () {
            console2(string).then(function () {
                resolve();
            });
        });
    });
}
function console1(value) {
    return new Promise((resolve) => {
        console.log(value + "1");
        resolve()
    });
}
function console2(value) {
    return new Promise((resolve) => {
        console.log(value + "2");
        resolve()
    });
}
consoleAll('value-')

В этом случае правильный результат был ниже:

value-1
value-2

Но когда он передается внутри цикла, он не создает потокправильно и вызывает функции совершенно не в порядке

function consoleAll(string) {
    return new Promise(function (resolve) {
        console1(string).then(function () {
            console2(string).then(function () {
                resolve();
            });
        });
    });
}
function console1(value) {
    return new Promise((resolve) => {
        console.log(value + "1");
        resolve()
    });
}
function console2(value) {
    return new Promise((resolve) => {
        console.log(value + "2");
        resolve()
    });
}

//Call
['h1-', 'h2-', 'h3-'].forEach(function (string) {
  consoleAll(string)
});

На этот раз вместо записи приведенного ниже результата:

h1-1
h1-2
h2-1
h2-2
h3-1
h3-2

выводится это:

h1-1
h2-1
h3-1
h1-2
h2-2
h3-3

Похожевызывает функцию console1 для всего массива, а затем вызывает console2.

Кто-нибудь знает правильный способ сделать этот вызов?PS.Мне все равно, если необходимо установить некоторые плагины, чтобы исправить это.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Если вы звоните new Promise(fn), fn внутри сразу же выполняется.Все .hen помещаются в стек для последующего выполнения, но сначала должен пройти весь .forEach.

Вы можете увидеть больше в этом коде:

function consoleAll(string) {
    return new Promise(function (resolve) {
        consoleLog(string, 1).then(function () {
            consoleLog(string, 2).then(function () {
                resolve();
            });
        });
        consoleLog(string, 3).then(function () {
            consoleLog(string, 4).then(function () {
                resolve();
            });
        });
    });
}
function consoleLog(value, tag) {
    return new Promise((resolve) => {
        console.log(value + tag);
        resolve()
    });
}

//Call
['h1-', 'h2-', 'h3-'].forEach(function (string) {
  consoleAll(string)
});

После initialition остальные обещания выполняются в случайном порядке.Также помните, что resolve() не останавливает выполнение ваших функций внутри вашей функции.Это будет выполнено!Однако, как только вы вызовете Promise, Promise изменится с Pending на Resolved, и он всегда вернет первое значение в resol.

0 голосов
/ 07 июня 2018

Вы должны позвонить logAll снова после , когда предыдущий асинхронный вызов завершен:

const values =  ['h1-', 'h2-', 'h3-'];
(function next(i) {
   if(i >= values.length) return;
   consoleAll(values[i]).then(function() {
      next(i + 1);
   });
})(0);

Или, если это уродливо, вот более современный способ:

(async function() {
   for(const string of ["h1-", "h2-", "h3"])
     await consoleAll(string);
})();

И, как я отметил в комментариях, consoleAll гораздо лучше записать как:

function consoleAll(str) {
  return console1(str).then(function() {
    return console2(str);
  });
}

или:

async function consoleAll(str) {
  await console1(str);
  await console2(str);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...