简体   繁体   English

Javascript - 承诺

[英]Javascript - Promises

Hello I need help on my code.您好,我的代码需要帮助。 I am not really familiar with Promises.我对 Promises 不是很熟悉。 I created a function called EmitRandomNumber().我创建了一个名为 EmitRandomNumber() 的 function。 In this function, after 2 full seconds (2000 ms), it generates a random number between 0 to 100. If the random number generated is below 80, I need to call that function again, up to 10 times, until the random number generated is greater than 80.在这个function中,经过整整2秒(2000毫秒),它会产生一个0到100之间的随机数。如果产生的随机数低于80,我需要再次调用那个function,最多10次,直到产生随机数大于 80。

 let attempt = 1; let rN; function EmitRandomNumber() { return new Promise((resolve, reject)=> { console.log(`Attempt #${attempt}. EmitRandomNumber is called.`); setTimeout(()=>{ let randomNumber = Math.floor(Math.random() * 100) + 1; rN = randomNumber; console.log("2 seconds have passed."); if(randomNumber>=80&&attempt<=10){ console.log(randomNumber,attempt); resolve(); }else if(randomNumber<80&&attempt<=10){ attempt++; console.log(`Random number generated is ${randomNumber}.`); console.log("==============================="); EmitRandomNumber(); } },2000); }); } let promise = EmitRandomNumber(); promise.then(()=>{ console.log(`Random number generated is ${rN};.;.`). console;log("==============================="); }).catch(()=>{ console.log("End"); });

I dont know if I am using the promise properly and sometimes when it is above 80 it doesnt execute whatever code is in the resolve.我不知道我是否正确使用了 promise,有时当它高于 80 时,它不会执行解析中的任何代码。 Can you help me how I can fix my code.你能帮我解决我的代码吗? Thank you!谢谢!

So the code is mostly good, you just did not specify when to 'reject' the promise.所以代码大部分都很好,你只是没有指定何时“拒绝”promise。 From what you described you want this to 'reject' (or display console.log('End')) IF the promise does not find a number after 10 attempts.根据您的描述,如果 promise 在 10 次尝试后找不到数字,您希望它“拒绝”(或显示 console.log('End'))。 So you only needed to add a condition (if attempt===10) etc.所以你只需要添加一个条件(如果尝试===10)等。

EDIT: The resolve and reject need to be returned.编辑:需要返回解决和拒绝。

let attempt = 1;
let rN; 
function EmitRandomNumber() {
    return new Promise((resolve, reject)=> {
        console.log(`Attempt #${attempt}. EmitRandomNumber is called.`);
        setTimeout(()=>{
            let randomNumber = Math.floor(Math.random() * 100) + 1;
            rN = randomNumber;
            console.log("2 seconds have passed.");
            if(randomNumber>=80&&attempt<=10){
                console.log(randomNumber,attempt);
                return resolve();
            }else if(randomNumber<80&&attempt<=10){
                attempt++;
                console.log(`Random number generated is ${randomNumber}.`);
                console.log("===============================");
                EmitRandomNumber();
//CHECK FOR CONDITION NUMBER OF ATTEMPTS
            } else if(attempt>10){
                 return reject();
            }
        },2000);
    });
  }


let promise = EmitRandomNumber();

promise.then(()=>{
    console.log(`Random number generated is ${rN}!!!!`);
    console.log("===============================");
}).catch(()=>{
    console.log("End");
});

It may be easier to read and reason about using async functions and await.使用异步函数和等待可能更容易阅读和推理。 Eg:例如:

const MAX_TRIES = 10;

const sleep = (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

const getRandomNumber = () => {
    return Math.floor(Math.random() * 100) + 1;
}

const getNumberWaitAndReturn = async () => {
    let rN = getRandomNumber();
    let attempt = 1;

    while (rN < 80 && attempt <= MAX_TRIES) {
        await sleep(2000);
        rN = getRandomNumber();
        attempt += 1;
    }

    if (attempt > MAX_TRIES) {
        console.log(attempt)
        throw new Error("No luck! It took more than 10 tries!")
    }

    return {
        rN,
        attempt
    }
}

const result = getNumberWaitAndReturn().then(v => {
    console.log(v)
});

You doing pretty good, you just need a little more practice to do it better, I highly recommend you start using closure instead of declaring global variables as you are doing into your code.你做得很好,你只需要更多的练习才能做得更好,我强烈建议你开始使用闭包,而不是像在代码中那样声明全局变量。

Before tell you how you can solve this, I will tell you that are the error, your function will only work as you expect if the first time its executed it generates a random number above of 80, otherwise the function will never be resolved, why?在告诉你如何解决这个问题之前,我会告诉你这是错误,你的 function 只有在第一次执行时会产生一个大于 80 的随机数,否则 function 将永远无法解决,为什么? that's because everytime you are calling the EmitRandomNumber() into the function itself you are creating a new Promise reference so the first one that you created is never handled because you create a new reference promise, so the new reference, it's no handle because your are calling inside the function itself and nobody is doing .then(...) .那是因为每次您将EmitRandomNumber()调用到 function 本身时,您都在创建一个new Promise引用,因此您创建的第一个永远不会被处理,因为您创建了一个新的引用 ZB321DE3BDC299EC807E9F795D 句柄,因为它是新的引用,在 function 本身内部调用,没有人在做 .then .then(...)

So how to solve this?那么如何解决这个问题呢? First at all you need to create a closure to create this.首先,您需要创建一个闭包来创建它。

const emitRandomNumber = () => {
  const MAX_ATTEMPTS = 10;
  const MS_START_TIME = 2000;
  const MINIMUM_NUMBER = 80;
  const MAXIMUM_NUMBER = 100;
  let attempts = 0;
  const randomNumber = (max) => Math.floor(Math.random() * max);
  return new Promise((resolve, reject) => {
    const startRandomNumber = () => {
      attempts++;
      const number = randomNumber(MAXIMUM_NUMBER);
      if (number < MINIMUM_NUMBER && attempts <= MAX_ATTEMPTS) {
        return setTimeout(startRandomNumber, MS_START_TIME);
      }
      if (number < MINIMUM_NUMBER && attempts > MAX_ATTEMPTS) {
        return reject();
      }
      resolve(number);
    };
    setTimeout(startRandomNumber, MS_START_TIME);
  });
}

As you can see we are using closure to create function inside function body, so the only function that we call again it's the startRandomNumber function, so this won't generate new promise instances, instead we are keeping the same promise reference and we just execute the random number function until we reach the attempts. As you can see we are using closure to create function inside function body, so the only function that we call again it's the startRandomNumber function, so this won't generate new promise instances, instead we are keeping the same promise reference and we just execute随机数 function 直到我们尝试。

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

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