繁体   English   中英

带有承诺的 setTimeout

[英]setTimeout with Promises

我试图通过以下问题解决挑战:

实现一个 function,它将一个数字作为参数并在 x 毫秒后(在 1 到 100 毫秒的间隔之间。使用 setTimeout 并作为数学库中的地板和随机函数),没有控制台或接收到的参数的两倍。 然后,调用这个 function 5 次。 前任。:

不做任何处理,很容易注意到控制台上显示的值的顺序是随机的,不接受函数调用的顺序。 因此,要解决此问题,请使用回调、Promise 和 async / waitit 处理或订阅 setTimeout。

这是预期的行为:

let result;

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

目标是使用承诺、异步函数或回调来处理 setTimeout 的异步行为。 这就是我到目前为止所得到的,但没有成功:


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. 我想返回一个 promise 并设置超时时间,该超时时间是随机计算的毫秒数,直到解决数字的双倍 + 增加值(如果存在)。
  2. 即使等待 promise 导致异步 function,它仍会继续返回待处理的 promise
  3. 结果变量必须在每次计算时增加,但它们接收的是函数而不是双重结果

你实际上就快到了。 您只需将解析后的 promise 的值分配给result ,而不是直接分配 Promise object 。 这是通过使用result = await double(<param1>, <param2>)来完成的。

但是,由于 JS 还不支持顶级 await,您需要将整个result分配逻辑包装在另一个异步 function 中,然后这样调用它:

 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 function 似乎仅用作包装器。 您的代码可以很容易地重写,以便您立即执行计算,但只需稍等片刻即可解决 promise:

 // 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);

您已接近解决方案。 这不起作用的原因如下:

double 是异步 function。 这意味着它不会返回 10、20 或任何其他数字,而是返回尽快解析为该数字的 Promise(在这种情况下,在超时之后)。

这意味着您应该将代码包装到另一个异步 function 并使用 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”方法代表另一种处理异步函数的方法:它是任何 promise 的常用方法。 请记住,任何异步 function 都会在后台返回 promise(即使未明确指定)。 await 语法只是处理 then 调用的语法糖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM