Когда выполняется асинхронность, ожидание, обещание.все, что нужно в JavaScript?

#javascript #performance #promise #async-await #synchronization

#javascript #Производительность #обещание #async-await #синхронизация

Вопрос:

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

Если у меня есть функция

 function count(n){
  let num = 0
  for(let i = n; i--;){
    num  
  }
  return num
}
 

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

 async function doSomething(){
  const one = await count(140000000)
  const two = count(one)
  return two
}
async function count(n){
  let num = 0
  for(let i = n; i--;){
    num  
  }
  return num
}
 

Но на самом деле я думаю, что это не столько значение, которое мне нужно передать в следующую функцию, чтобы она работала, так что в принципе все в порядке, не ожидая ответа, потому что он в основном отправляет функцию в качестве параметра, например

 async function doSomething(){
  const two = count(count(140000000))
  return two
}

function count(n){
  let num = 0
  for(let i = n; i--;){
    num  
  }
  return num
}
 

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

 async function parent2(){
  console.log('start')
  console.time('ALL')
  const numsToCount = [ 140000000, 170000000, 240000000 ]
  const res = await countNums2(numsToCount)
  // do other stuff with res
  const fin = count(res[0])
  console.timeEnd('ALL')
  console.log('end', fin)
}

async function countNums2(numsToCount){
  let countedNumsPromises = []
  for(let i = numsToCount.length; i--;){
    countedNumsPromises.push(count2(numsToCount[i]))
  }
  return Promise.all(countedNumsPromises)
}

async function count2(n){
  let num = 0
  for(let i = n; i--;){
    num  
  }
  return num
}
 

But then again realized I didnt really need promise.all even though its three functions that take some time but can be run together and could just do

 function parent1(){
  console.log('start')
  console.time('ALL')
  const numsToCount = [ 140000000, 170000000, 240000000 ]
  const res = countNums(numsToCount)
  console.timeEnd('ALL')
  console.log('end', res)
}

function countNums(numsToCount){
  let countedNums = []
  for(let i = numsToCount.length; i--;){
    countedNums.push(count(numsToCount[i]))
  }
  return countedNums
}

function count(n){
  let num = 0
  for(let i = n; i--;){
    num  
  }
  return num
}
 

И когда вы начинаете вкладывать такие вещи, как 3 раза, и более сложные вещи, очевидно, также сбивают с толку, но, возможно, попытка разобраться с некоторыми из этих более простых понятий поможет во всем. Нравится делать

 const parents = [
 {name: 'Jon', pets: ['dodo', 'goofy']},
 {name: 'Tammy', pets: ['gigi', 'laffy', 'bigbird']},
 {name: 'Tom', pets: ['ralphy', 'goose']},
]

const res = await Promise.all(parents.map(async parent => {
  const res2 = await Promise.all(parent.pets.map(async pet => {
   ...
  }
}
 

Также будет ли функция ожидания, как во многих примерах, отличаться от функции медленного подсчета?

 async function doSomething(){
  await Promise.all([wait(1000),wait(2000),wait(1500)])
  wait(1000)
}

async function wait(ms){
  return new Promise((resolve) => setTimeout(resolve, ms));
}
 

Так что, может быть, я много вам здесь рассказываю, но в основном, как мне реализовать синхронное программирование, а что не для правильной скорости и как правильно использовать async и promise.все против того, чтобы просто передавать все функции друг другу по мере необходимости и позволять функциям вычислять все ожидания предыдущей функции. Кроме того, я, похоже, обнаружил, что map reduce и filter, возможно, не самые быстрые, потому что вы будете перебирать одни и те же данные несколько раз, поэтому, в отличие от приведенного выше примера, я пытался придерживаться большего количества циклов for, но да, я не хочу, чтобы это отвлекало от ответа на вопрос, но это направление, в котором япытаюсь перейти.

Ответ №1:

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

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

Обещания — это объекты с .then функцией на нем. Вы можете вызвать .then и передать функцию, чтобы сообщить ей: «Эй, когда вы закончите ждать, пожалуйста, вызовите эту функцию». async / await просто упрощает синтаксис для работы с обещаниями: async функция автоматически создаст обещание, и await обработка обещания автоматически вызовет .then его.


Имея это в виду: приведенные вами примеры не имеют никакого отношения к async await. У вас есть куча синхронных вычислений, и вы не ждете ничего внешнего. Включение await в функцию map или цикл for не будет иметь никакого эффекта, кроме как запутать ваших коллег и очень незначительно увеличить время выполнения.

Комментарии:

1. Спасибо, что прояснили это, я, конечно, был смущен асинхронностью больше, чем ожидалось! Не понимал, что асинхронность не должна использоваться с внутренними обычными функциями js, но да, имеет смысл для вызовов выборки