1
class Parse{
  get(){

    let arr = {
      'first'  : 'Not change',
      'second' : 'Not change'
    }

    // Функция 1
    setTimeout(()=>{
      console.log('Firstй')
      arr.pop = 'change'
    }, 5000)

    // Функция 2
    setTimeout(()=>{
      console.log('Second')
      arr.sdd = 'change'
    }, 3000)

    return arr
  }
}

let pars = new Parse()
arr = pars.get()
console.log(arr)

Нужно последовательно выполнить две асинхронные функции и вернуть результат?

1 Answers1

1

Наиболее близко к коду вопроса

Чтобы получить результат асинхронно можно возвращать из функции Promise и брать результат от него:

pars.get().then(r=>console.log(r));

здесь pars.get возвращает Promise и в методе then определяется функция, которая будет вызвана, когда промис разрешится. При этом в параметре этой функции r будет лежать аргумент с которым была вызвана resolve, т.е массив arr:

resolve(arr);

В функции get необходимо вернуть новый промис. При создании промиса ему передается функция, которая будет выполняться асинхронно. По завершении выполнения требуется вызвать resolve и передать этому вызову результат:

return new Promise((resolve) =>{
                setTimeout(()=>{
                    console.log('First')
                    arr.pop = 'change'
                    setTimeout(()=>{
                        console.log('Second')
                        arr.sdd = 'change'
                        resolve(arr);
                    }, 3000);
                }, 5000);
            });

Рабочий вариант может выглядить так:

    class Parse{
        get(){
            let arr = {
                'first'  : 'Not change',
                'second' : 'Not change'
            }
        return new Promise((resolve) =>{
            setTimeout(()=>{
                console.log('First')
                arr.pop = 'change'
                setTimeout(()=>{
                    console.log('Second')
                    arr.sdd = 'change'
                    resolve(arr);
                }, 3000);
            }, 5000);
        });
    }
}

let pars = new Parse()
pars.get().then(r=&gt;console.log(r));</code></pre>

Общий вариант последовательного вызова

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

function getHtml() {
    return new Promise((resolve, reject) => {
        const html = "html content";
        resolve(html);
    });
}

Promise имеет метод then. Этот метод принимает как минимум один параметр - функцию, которая будет вызвана, когда в промисе будет вызвана resolve. Эта функция параметром принимает значение с которым был вызван resolve. В этой функции можно обработать результат асинхронной функции, и если необходимо, то запустить новую асинхронную функцию и вернуть ее результат (т.е. новый Promise):

getHtml()
    .then(r => {
        // делаем что-то с содержимым html
        return getImage(r);
    })

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

function getHtml() {
 return new Promise((resolve, reject) => {
  const html = "html content";
  resolve(html);
 });
}

function getImage() { return new Promise((resolve, reject) => { const image = "image"; resolve(image); }); }

function recognize() { return new Promise((resolve, reject) => { const text = "text"; resolve(text); }); }

getHtml() .then(r => { // делаем что-то с содержимым html return getImage(r); }) .then(r => { // делаем что-то с изображением return recognize(r); }) .then(r => { // просто выводим результат console.log(result: ${r}); }) .catch(e => { // что-то пошло не так console.log(error: ${e}); });

tilin
  • 2,840
  • Какой-то у вас грязный код в ответе. Несколько асинхронных функций вместе, переменная arr, а в ней объект, там где нужен const, используется let. – ReklatsMasters Oct 15 '17 at 15:46
  • @ReklatsMasters Я старался написать максимально близко к коду автора, чтобы были видны связные отличия. А Несколько асинхронных функций вместе - достаточно неплохой способ последовательно выполнить два setTimeout – tilin Oct 15 '17 at 16:01
  • При каких условиях может не сработать resolve? Пишу парсер. Последовательность действий такая: 1. Получаем Html-страницу парсим все что возможно с нее. 2. Запускаем эмулятор браузера (Nightmare.js) с помощью него получаем картинку с доп. информацией. 3. Распознаем текст с картинки с помощью ( tesseract). Resolve не хочет вызываться при выполнении 3 пункта. Есть ли какие-то ограничения в вызове? Т.е. у меня получилось 3 вложенных асинхронных ф-ии. – Артем Звайгзне Oct 16 '17 at 00:40
  • @Артем Звайгзне обновил ответ – tilin Oct 16 '17 at 07:01