Разница между синхронными и асинхронными функциями - PullRequest
1 голос
/ 03 марта 2020

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

Я сомневаюсь:

  1. , который больше похож на обычную функцию, синхронную или асинхронную функцию?
  2. , читая эту статью https://blog.expo.io/react-native-meets-async-functions-3e6f81111173, он говорит о возвращении обещаний и ожидании ответа. Итак, что же это за обещание, а также, если мы ожидаем ответа, разве это не должна быть синхронная функция?
  3. И, конечно, различия между синхронной и асинхронной функцией

Ответы [ 2 ]

3 голосов
/ 03 марта 2020

Javascript - это однопоточный язык, что означает, что функция, которая работает с такими вещами, как ввод-вывод, сокеты и сеть, в общем случае блокирует основной поток при выполнении. Чтобы иметь возможность писать параллельный код, который не блокирует основной поток с задачами, которые могут быть медленными, JS использует так называемое Событие L oop. Таким образом, асинхронная c функция - это просто функция, которую можно поместить в очередь и проверить результаты функции позже, не блокируя основной поток.

Вы можете узнать больше о событии L oop на MDN и просмотр этого выступления Филиппа Робертса

1 голос
/ 03 марта 2020

Это сложная тема c при переходе с других языков программирования. Используя вашу терминологию, «нормальная» функция похожа на синхронную функцию.

Я бы порекомендовал MDN документы для ожидания . Прочитайте эту страницу и затем запустите пример f1 - я включил его ниже с парой улучшений:

  1. Я добавил метки времени в console.log, чтобы время стало более очевидным
  2. Я добавил console.log операторы непосредственно до и после вызова f1().

Ключевое слово await не означает ожидание (или блокирование) в асинхронном режиме c функция. Он разделяет поток выполнения, приостанавливая функцию f1 (которая будет возобновлена ​​примерно через 2 секунды) и возвращая Promise вызывающей стороне, которая позволяет вызывающей функции asyn c выбирать, хочет ли он ожидать результата функция asyn c или нет. В приведенном ниже коде мы распечатываем результат вызова f1(), но мы решили не ожидать отложенного результата, а просто продолжаем переход к следующему console.log.

Запустите этот код в Node.js :

///////////////////////////////////////////////////////////////////////
// This is just setting up timestamps for console.log
///////////////////////////////////////////////////////////////////////
const oldlog = console.log;

console.log = function () {
  var args = [].slice.call(arguments);
  oldlog.apply(console.log,[getTimestamp()].concat(args));
};

const getTimestamp = () => '[' + (new Date()).toISOString() + ']';

///////////////////////////////////////////////////////////////////////
// Real code starts here
///////////////////////////////////////////////////////////////////////
function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  console.log('enter f1');
  const x = await resolveAfter2Seconds(10);
  console.log('exit f1, x =', x);
  return x;
}

console.log('before f1');
const y = f1();
console.log('after f1, y =', y);

При запуске это приведет к чему-то вроде следующего:

[2020-03-03T01:48:50.716Z] before f1
[2020-03-03T01:48:50.719Z] enter f1
[2020-03-03T01:48:50.720Z] after f1, y = Promise { <pending> }
[2020-03-03T01:48:52.725Z] exit f1, x = 10

Обратите особое внимание, что мы видим after f1 log до , который мы видим exit f1 журнал. Поток выполнения был разделен и f1() был приостановлен, а вызывающий f1() продолжил. Выполнение f1() возобновилось примерно через 2 секунды.

Теперь сравните это с тем, что произойдет, если вместо await мы получим результат от вызова f1(). Обратите внимание, что поскольку мы сейчас используем await, мы должны заключить код в async (на самом деле это асин c IIFE ), поскольку await можно использовать только внутри функции async.

// console.log('before f1');
// const y = f1();
// console.log('after f1, y =', y);

(async () => {
  console.log('before f1');
  const y = await f1();
  console.log('after f1, y =', y);
})();

Теперь вывод выглядит следующим образом:

[2020-03-03T02:19:18.122Z] before f1
[2020-03-03T02:19:18.124Z] enter f1
[2020-03-03T02:19:20.130Z] exit f1, x = 10
[2020-03-03T02:19:20.130Z] after f1, y = 10

Обратите внимание, что теперь, поскольку вызывающий абонент решил дождаться результата вызова f1(), мы видим after f1 и exit f1 журналы в обратном порядке (и в «обычном» порядке, используя вашу терминологию). И теперь результат f1() равен 10, а не ожидающему выполнения Обещанию.

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

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