簡體   English   中英

Javascript - 承諾

[英]Javascript - Promises

您好,我的代碼需要幫助。 我對 Promises 不是很熟悉。 我創建了一個名為 EmitRandomNumber() 的 function。 在這個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"); });

我不知道我是否正確使用了 promise,有時當它高於 80 時,它不會執行解析中的任何代碼。 你能幫我解決我的代碼嗎? 謝謝!

所以代碼大部分都很好,你只是沒有指定何時“拒絕”promise。 根據您的描述,如果 promise 在 10 次嘗試后找不到數字,您希望它“拒絕”(或顯示 console.log('End'))。 所以你只需要添加一個條件(如果嘗試===10)等。

編輯:需要返回解決和拒絕。

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

使用異步函數和等待可能更容易閱讀和推理。 例如:

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

你做得很好,你只需要更多的練習才能做得更好,我強烈建議你開始使用閉包,而不是像在代碼中那樣聲明全局變量。

在告訴你如何解決這個問題之前,我會告訴你這是錯誤,你的 function 只有在第一次執行時會產生一個大於 80 的隨機數,否則 function 將永遠無法解決,為什么? 那是因為每次您將EmitRandomNumber()調用到 function 本身時,您都在創建一個new Promise引用,因此您創建的第一個永遠不會被處理,因為您創建了一個新的引用 ZB321DE3BDC299EC807E9F795D 句柄,因為它是新的引用,在 function 本身內部調用,沒有人在做 .then .then(...)

那么如何解決這個問題呢? 首先,您需要創建一個閉包來創建它。

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隨機數 function 直到我們嘗試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM