在 for 循环的 if 语句中使用来自 promise 的 resolve 值

Using resolve value from promise in if statement of for loop

我有如下代码。实际功能是从API查询历史数据。例如,数组中的每个项目都与一家公司相关,因此每次迭代都是 return 该公司的历史数据。历史数据函数在setTimeOut函数中,为了调节请求的数量,因为API只允许在特定时间段内使用特定数量。

每次您提出请求时,您的津贴都会减少(这就是 getRemainingAllowance 承诺的目的。因此,如果剩余津贴低于 2000,我会尝试打破循环。

有什么方法可以 return 承诺中的解析值,以便我可以在 if 语句中使用它来打破循环?

我也试过 result = resolvedValue(没有 var)使其成为全局变量,但我仍然未定义 - 我还读过全局变量并不总是正确的方法)。

for (var i = 0; i < arr.length; i++) {

    const historical = require('./historic')

    getRemainingAllowance().then((resolvedValue) => {
        var result = resolvedValue

    })

    if (result < 2000) {
        break
    } else {
        setTimeout(function() {
            historical.getHistoric(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
        }, 3000 * (i + 1))
    }
}

我认为最好的方法是使用 async/await,因为它更干净。

async function doWork() {
    for (var i = 0; i < 100; i++) {
        const result = await getRemainingAllowance();
        // use your returned value
    }
}

你也可以使用经典的 promises 来做到这一点,但它有点奇怪:

var counter = 0;
function doWork() {
    getRemainingAllowance().then((result) => {
        // process your result
        counter++;
        if (counter < 100) {
           doWork(); // do it again until you hit the limit
        }
    });
}

首先,将 require 语句移出循环体,其次,您可以使用 async-await 语法重写代码,如下所示。您也不需要 setTimeout() 在请求之间添加延迟。

for (var i = 0; i < arr.length; i++) {
    const result = await getRemainingAllowance();

    if (result < 2000) {
        break;
    } else {
        historical.getHistoric(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
        await sleep(2);  // delay of 2 seconds
   }
}

sleep() 函数将秒数作为参数,returns 一个 Promise 在作为参数传递的秒数后解析。

function sleep(seconds) {
   return new Promise((resolve, reject) => {
       setTimeout(resolve, seconds * 1000);
   });
}

请记住,await 关键字只能在 async 函数中使用。