Дождитесь завершения вложенного обещания JS, прежде чем разрешать исходное обещание. - PullRequest
0 голосов
/ 02 января 2019

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

Оригинальный код

function getSomething(text) {
    return new Promise(function (resolve, reject) {
        getElse(text).then(function (items) {
            if (items.length !== 0) {

                /* Stuff here */

                getElseElse(box).then(function (moreItems) {

                    /* Stuff here */

                    return array;
                }.then(function (array) {
                    var promise = new Promise(function (resolve, reject) {
                        /* anotherFunction() is asynchronous */
                        result = anotherFunction(array); <-- Spot 1
                    });
                    promise.then(function () { });
                });

                return resolve(result); <--- Spot 2

            }
            else {
                return resolve(null);
            }
        });
    });
};

Обновленный код - лучше, но все еще работает не так, как я хочу.

function getSomething(text) {
    return getElse(text).then(function (items) {
        if (items.length !== 0) {

            /* Stuff here */

            return getElseElse(box).then(function (moreItems) {

                /* Stuff here */

                return array;
            }).then(anotherFunction);

        } else {
            return null;
        }
    });
}

Тогда внутри отдельной страницы просмотра у меня есть это:

getSomething(text).then(function (result) {
    /* Do something here using result */
    /* But result is undefined and I think still pending */
});

Я оптимизировал исходную функцию, используя помощь Томаса, но первоначальный вызов внутри представления все еще продолжается до формулировки result.

Я хочу, чтобы getSomething() полностью завершился и вернул result, прежде чем я выполню код внутри .then, который находится внутри представления. Пока это не достигнуто.

Я нашел пару постов, которые указали мне правильное направление Promise.all, но я не могу найти эту информацию, поэтому я надеялся, что кто-то может помочь объяснить это для моего конкретного ситуация.

Посты, которые помогли:

  1. Цепочка обещаний не ожидает выполнения обещаний до завершения
  2. Дождитесь разрешения вложенных обещаний
  3. Дождитесь завершения обещаний внутри Promise.all, прежде чем разрешить его

Решение

Первоначальный вопрос был решен Томасом в помеченном ответе. Последняя проблема была решена внутри anotherFunction() при дальнейшей проверке.

Первоначально:

function anotherFunction(array) {
    return new Promise(function (resolve, reject) {
        return anotherGet(parcels).then(function (list) {
            /* Do stuff here without a return */
        });
    });
}

Фиксированная версия:

function anotherFunction(array) {
    return anotherGet(parcels).then(function (list) {
        /* Do stuff here */
        return list;
    });
}

Ответы [ 2 ]

0 голосов
/ 02 января 2019

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

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

И последнее, что-то вроде .then(value => value) или .then(value => Promise.resolve(someFunction(value))) бессмысленно. Ваша оболочка вокруг anotherFunction в основном просто прошла через аргумент и вернула результат.

Итак, ваш псевдокод должен выглядеть примерно так:

function getSomething(text) {
  return getElse(text).then(function (items) {
    if (items.length !== 0) {
      /* Stuff here */
      return getElseElse(box).then(function (moreItems) {
        /* Stuff here */
        return array;
      }).then(anotherFunction);
    } else {
      return null;
    }
  });
}
0 голосов
/ 02 января 2019

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

Что-то вроде:

function getSomething(text) {
    return new Promise(function (resolve, reject) {
        getElse(text).then(function (items) {
            if (items.length !== 0) {

                /* Stuff here */

                getElseElse(box).then(function (moreItems) {

                    /* Stuff here */

                    return array;
                }.then(function (array) {
                    var promise = new Promise(function (resolve, reject) {
                        result = anotherFunction(array); <-- Spot 1
                    });
                    promise.then(function () { });

                    resolve(result); <--- Spot 2
                });    
            }
            else {
                resolve(null);
            }
        });
    });
};

Если он должен быть вложен в promise.then() выше, просто вставьте его туда.

Также обратите внимание, что вам не нужно возвращать свои разрешения. Просто позвоните им.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...