Nodejs, почему await ограничивается только асинхронными функциями? - PullRequest
0 голосов
/ 26 ноября 2018

Возможный дубликат await действителен только в асинхронной функции .

Я новичок в NodeJS, и я нашел концепцию async-await немного запутанной.После некоторого чтения и путаницы, это мое понимание того же.

Предположим, у меня есть функция sum, подобная этой.

function sum(a, b) {
  // print the numbers
  for (var i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  new Promise (resolve => {
    setTimeout(resolve, 1000);
  });
  return a+b;
}

function main() {
  let a = sum(5,2);
  console.log(a);
}

main();

Она выделяет новый поток для таймера.и продолжается с нормальным потоком.Сначала он печатает все числа, возвращает 7, а затем ждет 1 секунду, прежде чем выйти.

Но теперь я хочу выполнить строки в порядке их написания.Имеет смысл поставить ключевое слово await перед таймером Promise.

async function sum(a, b) {
  // print the numbers
  for (var i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  await new Promise (resolve => {
    setTimeout(resolve, 1000);
  });
  return a+b;
}

Issue 1: Здесь я не понимаю обязанности поставить async виспользуйте await.Только установка async просто заставляет функцию возвращать Promise вместо значения.поток неизменен.Он по-прежнему печатает все номера перед печатью 7.

Issue 2: Я думаю, что слово async перед функцией вводит в заблуждение, что вызовы функций будут асинхронными, хотя это не так.Есть какие-либо пояснения относительно дизайна?

Выпуск 3:

  • В NodeJS не существует понятия синхронного или асинхронного вызова функции, если у нас нет некоторыхфункция блокировки, как таймер, удаленные запросы и операции ввода-вывода.Вот здесь и появляется понятие async-await.В противном случае это всего лишь один поток, даже если программа имеет Promises.
  • Помещение async помимо функции просто заставляет ее возвращать Promise вместо значения.Это не меняет ход программы.Возможно, это просто добавляет некоторый дополнительный механизм для обработки await (если есть) просто предположение !! .
  • async не обязательно делает какую-либо функцию (или ее вызов) асинхронной,Вызов функции с ключевым словом async будет по-прежнему синхронным, если только он не содержит другого Promise, который заставляет его ждать.Вот тут и приходит await.

Правильно ли все мое понимание?

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

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

function sumLater(a, b) {
  return new Promise(resolve => {
    setTimeout(() => resolve(a+b), 1000);
  });
}

async function sum(a, b) {
  // print the numbers
  for (let i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  let result = await sumLater(a, b);
  // using the awaited result
  console.log("The awaited result is", result);
  return result;
}

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

async это столько жесигнал механизму JavaScript о том, что функция будет выполнена таким особым образом, а также читателям человеческого кода о том, что она возвращает Promise, а не возвращаемое значение (если только возвращаемое значение уже не было обещанием и не выполнялоне нуждается в переносе).

Большинство ваших проблем связано с терминологической путаницей.Не зацикливайтесь на буквальном значении терминологии.Ничто в JavaScript (кроме Web Workers) не является одновременным, и на первый взгляд одновременное и синхронное должно быть синонимами.В JavaScript синхронные средства «полностью выполняются в рамках одной и той же задачи», а асинхронные средства «заставляют новую задачу помещаться в стек выполнения», насколько я понимаю, более или менее.С этой точки зрения async означает , что означает, что функция будет асинхронной, поскольку значение «асинхронный» имеет в JavaScript.

0 голосов
/ 26 ноября 2018

Простое обещание возврата с использованием async-await или обещание на самом деле не делает функцию асинхронной.async-await или обещание использовать обработанные реальные асинхронные функции Javascript .

Асинхронные функции могут быть только setTimeout, setInterval, requestAnimationFrame и другие функции для более полной асинхронной функции, проверьте этот пост Как создать асинхронную функцию в javascript? .

Объясним это с помощью двух примеров, один с async-await, а другой с promise и чем они отличаются:

  1. обещание:

`` `

function main() {
    return new Promise( resolve => {
       console.log(1);
       resolve(true);
    });
}

main()
.then( result => {    // result will have whatever main promise will resolve.
    console.log(2);
});

console.log(3);

` ``

Если использование обещания или возвращающего обещания сделает функцию асинхронной, то порядок вывода будет

3
1
2

Однако простое возвращение обещания не делает функцию асинхронной, поэтому вывод равен

1
3
// Asynchronous happen here
2

Теперь Почему 2 после 3? , поскольку только асинхронная функция Javascript можетбыть асинхронным и переходит в стек вызовов, а затем в очередь событий, тогда функция обратного вызова .then( function() {}) является истинной асинхронной функцией javascript и, следовательно, такого поведения. Обратите внимание, что вызов main () возвращает функцию обещания. Это будет использоваться в разнице между обещанием и асинхронным ожиданием.

async-await

`` `

async function main() {
    console.log(1);
    return true;
}

main()
.then( result => {  // Result have whatever main function return.
    console.log(2);
});

console.log(3);

` ``

Аналогично приведенному выше, это также выдает

1
3
// Asynchronous happen here
2

В чем разница между async-await и обещанием? async-await может обрабатывать обещание только с использованием await и любой асинхронной функцией, которая не возвращает обещание и на месте, использует функцию обратного вызова, такую ​​как setTimeout,Функции setInterval, request.js, https.js и т. д. не могут быть обработаны с помощью async-await.Для обработки такой функции мы можем использовать только Promise, так как Promise использует функцию обратного вызова, таким образом, способность обрабатывать любую асинхронную функцию:

function timeout() {
    return new Promise( (resolve, reject) => {
        console.log(1);
        setTimeout( function() {
            console.log(2);
            resolve(true);
        }, 1000);
    });
}

async function main() {
    console.log(3);
    let result = await timeout();
    console.log(4);
    return result;
}

main()
.then( result => {
    console.log(5);
});

console.log(6);

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

3
1
6
// asynchronous happens here
2
4
5

Последний пример для подробного объяснения await, удаленного использования setTimeout из последнего примера:

function timeout() {
    return new Promise( (resolve, reject) => {
        console.log(1);
        console.log(2);
        resolve(true);
    });
}

async function main() {
    console.log(3);
    let result = await timeout();
    console.log(4);
    return result;
}

main()
.then( result => {
    console.log(5);
});

console.log(6);

Как ожидается, вывод:

3
1
2
6
// Asynchronous await here
4
5

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

0 голосов
/ 26 ноября 2018

Это все еще JavaScript, что означает, что он все еще работает в одном потоке.Ключевое слово await приостанавливает выполнение функции async в этой строке до тех пор, пока эта строка не разрешится, возможно, со значением, после которого выполнение функции продолжается внутри этой функции.Причина, по которой все числа печатаются первыми оба раза, состоит в том, что этот код находится перед любыми асинхронными вызовами.Выполнение, вероятно, кажется одинаковым в обоих ваших примерах, поскольку печать 100000 журналов занимает значительно больше времени, чем секунда, которую требуется для выполнения обещания.

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