Асинхронный Javascript: неожиданный результат - PullRequest
4 голосов
/ 11 июля 2019

Я учу себя асинхронному JS и написал небольшую тестовую программу, чтобы помочь мне лучше понять, как она работает.

Я ожидал с этим кодом, что четные числа будут проверяться не по порядку, так как я добавил задержку в функцию "TestPrime ()". Тем не менее, когда код выполняется, числа работают в последовательности. Другими словами, я ожидал что-то вроде:

3 простое 5 простое 2 простое ...

async function TestPrime(num) {

    for(var i = 2; i < num; i++){

        let res = num % i;

        if (num % 2 == 0) {
            setTimeout(()=>{}, 1500);
        }

        if (res == 0) {
            return ({number: num, prime: false});
        }
    }

    return ({ number: num, prime: true});
}

const f = ()=>{
    for (var i = 2; i <= 50; i++){

        if (TestPrime(i).then(p => { 
            if (p.prime)
                console.log('%s is prime', p.number);
            else    
                console.log('%s is NOT prime', p.number);
        }));
    }
}

f();

Я уверен, что это просто недоразумение по поводу асинхронного программирования JS, но я был бы очень признателен, если бы кто-то там смог меня поправить.

Заранее большое спасибо!

Ответы [ 2 ]

3 голосов
/ 11 июля 2019
setTimeout(()=>{}, 1500);

ничего не делает.Это по сути НО-ОП.

Если вы хотите отложить асинхронный метод, вы можете определить метод задержки следующим образом:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

Возвращает Promise, которое разрешается через ms миллисекунд.

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

async function foo(){
   // do something
   await delay(1500);
   // do something else
}
2 голосов
/ 11 июля 2019

Единственное, что вы задерживаете, - это вызов ()=>{} - функции, которая ничего не делает .

setTimeout - это не спящая функция.В этом смысл асинхронности: все остальное продолжается без ожидания.


Чтобы иметь реальную задержку, вам нужно остановить выполнение своего обещания до истечения времени ожидания.

Склассический синтаксис обещания, который будет выглядеть так:

function TestPrime(num) {
  return new Promise(resolve => {
    for (let i = 2; i < num; i++) {
      let res = num % i;
      if (num % 2 == 0) {
        return setTimeout(() => resolve({
          number: num,
        }), 1500);
      }
      if (res == 0) {
        return resolve({
          number: num,
        });
      }
    }
    resolve({
      number: num,
    });
  });
}
const f = () => {
  for (var i = 2; i <= 50; i++) {
    if (TestPrime(i).then(p => {
        if (p.prime) console.log('%s is prime', p.number);
        else console.log('%s is NOT prime', p.number);
      }));
  }
};
f();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...