setTimeout with Promises



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

实现一个函数,该函数将数字作为参数,并在x毫秒后(间隔为1到100毫秒。使用setTimeout以及数学库中的floor和随机函数(,无需控制台或使用两倍的接收参数。然后,调用此函数5次。示例:

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

这是预期的行为:

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

目标是用promise、异步函数或回调处理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产生异步函数,它也会继续返回一个挂起的promise
  3. 每次计算的结果变量都必须增加,但它们接收的是函数,而不是双重结果

您实际上已经接近目标了。您所需要的只是将解析的promise的值分配给result,而不是直接分配promise对象。这是通过使用result = await double(<param1>, <param2>)来完成的。

然而,由于JS还不支持顶级等待,您需要将整个result分配逻辑封装在另一个异步函数中,然后这样调用它:

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

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

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

这意味着您应该将代码封装到另一个异步函数中,并使用wait来处理promise:

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

注意;那么";方法代表了处理异步函数的另一种方法:它是任何promise的常用方法。请记住,任何异步函数都会在后台返回promise(即使没有明确指定(。wait语法只是处理then调用的语法糖。

最新更新