Обещание JavaScript: сообщение об ошибке появляется после исправленных - PullRequest
0 голосов
/ 04 мая 2018

Я реализую функцию Generator, которая использует цикл for, чтобы пройти заданный диапазон чисел и найти простые числа.

function * findPrimeNumbers (from, to) {
    for (let i = from; i <= to; i++) {
        let isCurrentNumber = true
        for (let j = 2; j < i; j++) {
            if (i % j === 0) {
                isCurrentNumber = false
                break
            }
        }
        if (isCurrentNumber) {
            yield i
        }
    }
}

Обещание вызывается для каждого простого числа и получает его имя (например, когда задано 3, будет возвращено «три»).

Мой вопрос: почему, когда дается число 2 и выдается ошибка, сообщение регистрируется после разрешенных. Моя цель - войти в систему, когда запрашивается номер.

const data = [
    {
        id: 5,
        name: 'five'
    },
    {
        id: 7,
        name: 'seven'
    },
    {
      id: 3,
      name: 'three'
    },
    // Two is a prime number and it will not be found.
    // The error message will come after the resolved ones although it is the first number to be requested.
    // Why?
    // {
    //     id: 2,
    //     name: 'two'
    // }
]

function getNumberName (primeNumber, numbers) {
    return new Promise((resolve, reject) => {
        const retrievedNumber = numbers.find(number => number.id === primeNumber)

        if (retrievedNumber) {
            resolve(retrievedNumber.name)
        } else {
            reject(new Error(`The requested number ${primeNumber} is not found!`))
        }
    })
}

const result = findPrimeNumbers(2, 10) // start executing the generator

let isDone = false

while (!isDone) {
    let current = result.next()

    isDone = current.done

    if (!isDone) {
        let numberName = getNumberName(current.value, data)

        numberName
            .then(name => console.log(name))
            .catch(error => console.log(error.message))
    }
}

Результат

three
five
seven
The requested number 2 is not found!

Заранее спасибо!

1 Ответ

0 голосов
/ 04 мая 2018

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

const result = findPrimeNumbers(2, 10); // start executing the generator

checkNextNumber(result)

function checkNextNumber(result) {
  let current = result.next();

  if(current.done) return;

  let numberName = getNumberName(current.value, data);

  numberName
    .then(name => console.log(name))
    .catch(error => console.log(error.message))
    .then( () => checkNextNumber(result) )
}

Какие выходы:

The requested number 2 is not found!
three
five
seven

Редактировать : Использовать асинхронный

Если вам не нравится рекурсия, вы можете использовать асинхронную функцию (которую, я полагаю, вы можете использовать, так как в любом случае вы уже используете генератор). В качестве бонуса я использую цикл for of, который делает ваш код более читабельным:

async function checkNextNumberAsync(result) {
  for(let current of result) {
    try {
      let name = await getNumberName(current, data);
      console.log(name);
    } catch(e) {
      console.log(e.message)
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...