setTimeout с обещаниями - PullRequest
       9

setTimeout с обещаниями

0 голосов
/ 09 апреля 2020

Я пытаюсь решить задачу с помощью следующего вопроса:

Реализует функцию, которая принимает число в качестве параметра и через x миллисекунд (между интервалом от 1 до 100 мс. Используйте setTimeout и как функции пола и случайные функции из библиотеки Math), без консоли или с дважды полученным параметром. Затем вызовите эту функцию 5 раз. Пример :

Без выполнения какой-либо обработки легко заметить, что порядок значений, отображаемых на консоли, является случайным и не принимает порядок вызова функций. Поэтому для решения этой проблемы обработайте или подпишитесь на setTimeout с помощью функции обратного вызова, Promise и asyn c / waitit.

Это ожидаемое поведение:

let result;

result = double(5, 0); // returns 10
result = double(12, result); // returns 34
result = double(2, result); // returns 38

Цель - обрабатывать асинхронное поведение setTimeout с помощью обещаний, асин c функций или обратных вызовов. Это было то, что я получил до сих пор, но безуспешно:


function promisify(number, increase){
    return new Promise(resolve => setTimeout(() => resolve(number * 2 + increase), 100))
}

async function double(number, increase) { 
   const value = await promisify(number, increase); 
   return value;
}

let result; 
result = double(5, 0)
result = double(10, result)
result = double(20, result)

console.log(result)
  1. Я хочу вернуть обещание с установленным тайм-аутом, который был случайным подсчетом в миллисекундах до разрешения двойного числа + увеличения значение, если оно существует.
  2. Даже ожидая, когда обещание приведет к выполнению функции asyn c, оно продолжает возвращать ожидающее обещание
  3. Переменные результата должны увеличиваться при каждом вызове c, но они получение функций вместо двойного результата

Ответы [ 2 ]

3 голосов
/ 09 апреля 2020

Ты на самом деле почти там. Все, что вам нужно, это присвоить значение разрешенного обещания result, вместо того, чтобы назначать объект Promise напрямую. Это делается с помощью result = await double(<param1>, <param2>).

. Однако, поскольку JS еще не поддерживает ожидание верхнего уровня, вам нужно обернуть все result логи назначения c в другой асин c функции, а затем вызвать его так:

function promisify(number, increase){
    return new Promise(resolve => setTimeout(() => resolve(number * 2 + increase), 100))
}

async function double(number, increase) { 
   const value = await promisify(number, increase); 
   return value;
}

async function run() {
  let result; 
  result = await double(5, 0)
  result = await double(10, result)
  result = await double(20, result)

  console.log(result)
}

run();

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

// Simply forces the async operation to wait for a set duration
function wait(duration){
    return new Promise(resolve => setTimeout(resolve, duration));
}

async function double(number, increase) {
   await wait(100);
   return (number * 2) + increase;
}

async function run() {
  let result; 
  result = await double(5, 0)
  result = await double(10, result)
  result = await double(20, result)

  console.log(result)
}

run();

Таким образом, вы можете реализовать желаемое рандомизированное время ожидания вопроса, если хотите, например:

// Waits between [1, 1000] milliseconds
await wait(Math.random() * 1000);
1 голос
/ 09 апреля 2020

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

double - это асинхронная c функция. Это означает, что он не возвращает 10, 20 или любой другой номер, но обещание, которое разрешается к этому номеру как можно скорее (в данном случае, после истечения времени ожидания).

Это означает, что вы должны перенести код в другую asyn c функцию и используйте await для обработки обещаний:

async function doPrint() {
    let result; 
    result = await double(5, 0)
    result = await double(10, result)
    result = await double(20, result)

    console.log(result)

    return result;
}

doPrint().then(function(result) { console.log('Returned result ' + result); 

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

...