Как мне смешать, ожидаем () с обещаниями, не связанными с транспортиром в цепочках обещаний транспортира? - PullRequest
2 голосов
/ 18 июня 2019

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

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

a().then(() => {
    x();
    b().then(() => {
        y();
        c().then(() => z());
    });
});

должно быть таким же, как:

a().then(() => {
    x();
    b();
}).then(() => {
    y();
    c();
}).then(() => z());

, который также должен быть таким же (если я использовал ES6 на работе, а я нет):

await a();
await x();
await b();
await y();
await c();
await z();

Вы можете увидеть мой полный код здесь вместе с выводом, который я получил: https://github.com/cpjust/TypeScriptTest/tree/dev/specs

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

1 Ответ

0 голосов
/ 18 июня 2019

Ваш один вопрос содержит много подвопросов, но все они хороши. Поэтому лучше идти один за другим, и я изо всех сил стараюсь объяснить, что может помочь вам решить вашу проблему.

first_spec.ts

 it('promise chain 1', function () {
        /* Prints the following:
        [TRACE] default - Start
        [DEBUG] default - Sleeping for 100 ms...
        [TRACE] default - End
        [INFO] default - --1
        [DEBUG] default - Sleeping for 200 ms...
        [INFO] default - --2
        [DEBUG] default - Sleeping for 300 ms...
        [INFO] default - --3
        [INFO] default - --done
        */
        logger.trace("Start");

        printLater("--1", 100).then(() => {
            printLater("--2", 200).then(() => {
                printLater("--3", 300).thenFinally(() => {
                    logger.info("--done");
                });
            });
        });

        logger.trace("End");
    });
  • Это очень прямолинейно. printLater возвращает обещание browser.sleep, поэтому ему нужно подождать определенное время, а затем разрешить. Это означает, что каждый printLater должен быть завершен перед переходом к следующему. Надеюсь, у вас нет сомнений в этом блоке it.

    it ('цепочка обещаний 1.1', function () { / * Печатает следующее: [TRACE] по умолчанию - Пуск [DEBUG] по умолчанию - спит в течение 100 мс ... [TRACE] по умолчанию - Конец [ИНФО] по умолчанию - --1 * / logger.trace ( "Start");

        nativePromise("--1", 100).then(() => {
            nativePromise("--2", 200).then(() => {
                nativePromise("--3", 300).finally(() => {
                    logger.info("--done");
                });
            });
        });
    
        logger.trace("End");
    });
    

В этом случае nativePromise создает объект Promise и вызывает внутри него printLater. Позвольте мне объяснить, как происходит поток. Когда мы вызываем функцию nativePromise, она напрямую возвращает объект обещания, который в настоящее время находится в состоянии ожидания по умолчанию (поскольку существует три состояния любого объекта обещания: разрешение / отклонение / ожидание). Теперь, используя затем в nativePromise, ожидаем состояние разрешения / отклонения, но оно остается в состояние ожидания в течение неопределенного времени до истечения времени ожидания теста. По этой причине тест срабатывает в одной точке и ничего не делает. Последний момент заключается в том, что мы получаем некоторый вывод для первого nativePromise из-за асинхронного поведения. поскольку есть функция printLater, которая работала асинхронно и регистрировала свой результат.

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

function nativePromise(msg, time) {
        return new Promise((resolve) => {
            resolve(printLater(msg, time));
        });
    }

Примечание. Рекомендуется всегда разрешать / отклонять обещания.

it('await promise 3.1', async function () {
        /* Prints the following:
        [TRACE] default - Start
        [DEBUG] default - Sleeping for 100 ms...
        [INFO] default - --1
        */
        await logger.trace("Start");

        await nativePromise("--1", 100);
        await nativePromise("--2", 200);   // Gets stuck after "--1"
        await nativePromise("--3", 300);
        await logger.info("--done");

        await logger.trace("End");
    });

Для предыдущего фрагмента кода причина та же, что я упоминал ранее. await также ожидает обещания разрешить / отклонить. Если он ничего не возвращает, тогда подождите и застрянет в одной точке.

Мы используем await, чтобы сделать код чище. Внутренне он также ожидает обещание разрешить / отклонить и не возвращает объект обещания. await получает значение из объекта обещания и возвращает.

Примечание 1: ожидайте, что Жасмин ждет, пока поток управления опустеет, прежде чем выполнять какие-либо дальнейшие действия. см. Эту ссылку от Транспортира

ПРИМЕЧАНИЕ 2. Protractor Promise, который на самом деле является webdriver.Promise устарел в Protractor и webdriverJs. Поэтому, если возможно, не использовать их.

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