обещание цепочки над асинхронным ожиданием - javascript [duplicate]

Строки в Java неизменяемы. Это означает, что всякий раз, когда вы пытаетесь изменить / изменить строку, вы получаете новый экземпляр. Вы не можете изменить исходную строку. Это сделано для того, чтобы эти экземпляры строк могли кэшироваться. Типичная программа содержит множество ссылок на строки и кеширование этих экземпляров, что может уменьшить объем памяти и увеличить производительность программы.

При использовании оператора == для сравнения строк вы не сравниваете содержимое строки , но фактически сравнивают адрес памяти. Если они равны, в противном случае они вернут true и false. Если значение равно в строке, сравнивает содержимое строки.

Итак, вопрос в том, что все строки кэшируются в системе, как получается == возвращает false, тогда как equals возвращает true? Ну, это возможно. Если вы создадите новую строку, например String str = new String("Testing"), вы создадите новую строку в кеше, даже если в кеше уже содержится строка с тем же содержимым. Короче говоря, "MyString" == new String("MyString") всегда будет возвращать false.

Java также говорит о функции intern (), которая может использоваться в строке, чтобы сделать ее частью кеша, поэтому "MyString" == new String("MyString").intern() вернет true.

Примечание: == оператор намного быстрее, чем равен только потому, что вы сравниваете два адреса памяти, но вы должны быть уверены, что код не создает новые экземпляры String в коде. В противном случае вы столкнетесь с ошибками.

6
задан Vikas Bansal 28 November 2017 в 07:11
поделиться

3 ответа

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

. Вернуться к основному вопросу, следует использовать async/await, а не .then с необработанными обещаниями?

Имейте в виду, что async/await - это просто синтаксический сахар над сырые обещания, поэтому не должно оказывать большого влияния на общую производительность. Тем не менее, это делает ваш код более линейным, что избавляет от когнитивных накладных расходов от разработчика.

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


Некоторое недоразумение:

Столбец ошибок, возвращенный из цепочки обещаний, не дает никакого представления о том, где произошла ошибка.

Это неверно. Быстрая проверка:

function error() {
    return new Promise(function(res, rej) {
        res(undefined()); // uh oh
    });
}

error().then(console.log, e => console.log("Uh oh!", e.stack));

показывает весь стек ошибок, включая местоположение.

9
ответ дан Derek 朕會功夫 15 August 2018 в 19:11
поделиться
  • 1
    Вы совершенно правы, и я согласен с вами, и мне просто нужно подтвердить еще одну вещь. Предположим, что если у меня есть некоторые асинхронные проверки e.g. checking the availability of user name, email, phone number.. В случае неудачи какой-либо из этих проверок мне придется использовать throw в async function , так что await получит ошибку. В обещании мне не нужно использовать throw, я просто reject is't it reject vs throw. На сервере, где одна строка кода может выполняться миллионы раз. Простите меня за мое невежество, я знаю, это звучит глупо ... но не может устоять. Спасибо, что не жалели времени на ответ. – Vikas Bansal 28 November 2017 в 07:41
  • 2
    @VikasBansal. Выбрасывание ошибки внутри функции async может выполняться интерпретатором по-разному, поэтому вам нужно будет проверить ее, чтобы быть уверенным. Попробуйте использовать оба из них в какой-то реальной среде тестирования и проанализируйте время, которое они берут после этого. – Derek 朕會功夫 28 November 2017 в 07:57

На основе ответа unional :

Вы можете добиться того же поведения, что и Promise.all с async/await

function foo() {
  Promise.all([backend.doSomething(), backend.doAnotherThing()])
    .then(([a, b]) => {
       return a + b
    })
}

async function foo() {
  const a = backend.doSomething()
  const b = backend.doAnotherThing()
  return await a + await b
}

Резервные задачи выполняются одновременно и мы ждем, когда оба будут закончены, прежде чем мы вернемся. См. Также пример MDN, который я написал

. Основываясь на этом, я не уверен, есть ли какое-либо преимущество в производительности для прямого использования обещаний над async/await.

1
ответ дан spygi 15 August 2018 в 19:11
поделиться

Как и большинство вещей, ответ «зависит от».

Прежде чем говорить о производительности, более важным аспектом является ремонтопригодность кода и ограничение async / await vs raw Promise.

async / await - отличный способ выполнить асинхронный код последовательно, в то время как Promise позволяет одновременно запускать асинхронный код.

async function foo() {
  const a = await backend.doSomething()
  const b = await backend.doAnotherThing()
  return a + b
}

В приведенном выше коде backend.doAnotherThing() не будет выполняться до тех пор, пока backend.doSomething() не вернется. С другой стороны:

function foo() {
  Promise.all([backend.doSomething(), backend.doAnotherThing()])
    .then(([a, b]) => {
       return a + b
    })
}

выполнит оба вызова и дождитесь завершения обоих.

Как вы упомянули о преимуществах async / await, I лично использовать его широко. За исключением случаев, описанных выше.

Если вам нужна производительность и вам, разница в производительности между async / await и Promise важнее, чем преимущество чтения async / await по Promise, всеми средствами идти вперед.

Пока это сознательный выбор, вы должны быть в порядке.

6
ответ дан unional 15 August 2018 в 19:11
поделиться
  • 1
    На данный момент это nitpicking, но ваш пример async может быть переписан как таковой , чтобы выполнить их одновременно. Оба метода async/await и raw обещания отлично подходят для одновременного запуска async-кода. – Derek 朕會功夫 28 November 2017 в 20:50
  • 2
    хороший пример. Это хороший способ сделать это. – unional 28 November 2017 в 20:53
Другие вопросы по тегам:

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