如何使用 for 循环来重申 promise 函数?

How can I use a for loop to reiterate a promise function?

我有以下代码用于从 Amazon Web 服务器 API 获取 JSON 数据。

var json1 = new Promise((resolve, reject) => {
     fetch(url[0])
     .then(r => {
         resolve(r.json())
     })
     .catch(err => {
         reject(err)
     })
})

我使用不同的 url 和 json 变量重复了 14 次,并在最后使用 return 承诺。

return Promise.all([json1,json2,json3,json4,json5,json6,json7,json8,json9,json10,json11,json12,json13,json14]).then(function(values) {
    return values;
});

这可行,但它占用了 150 多行。我想创建一个 for 循环,它使用 for 循环运行相同的代码。我创造了这个...

for(var jsonCount = 0;jsonCount<url.length-1;jsonCount++){
    jsonArr[jsonCount] = new Promise((resolve, reject) => {
        fetch(url[jsonCount])
        .then(r => {
            resolve(r.json())
        })
        .catch(err => {
            reject(err)
        })
    })
}

这是行不通的,因为 promise 函数返回时未定义,即使它被 await 函数调用。

const data = await fetchURL(urlToQuery())

有人对这项工作有什么建议吗? JSON 正在 return 编辑。

感谢您的帮助。

编辑:这是更大的代码块。

function fetchURL(urls) {
    let fetchJson = url => fetch(url).then(response => response.json());
    Promise.all(urls.map(fetchJson)).then(arr => {
        return arr;
    });
(async function() {
    const data = await fetchURL(urlToQuery())
    console.log(data);
        for(var r=0;r<numStations;r++){
            if (data[r] == ""){
                onlineArr[r] = false;
                wdDataArr[r].push(cardinalToDeg(stationHistAvgArr[r]));
                wsDataArr[r].push(0);

我认为这个例子可以帮助到你:

// Mock async function
const getDataAsync = callback => {
    setTimeout(
        () => callback(Math.ceil(Math.random() * 100)),
        Math.random() * 1000 + 2000
    )
}

// Create the promise
const getDataWithPromise = () => {
    return new Promise((resolve, reject) => {
        try {
            getDataAsync(resolve);
        } catch(e) {
            reject(e);
        }
    });
}

// Using the promise one time
getDataWithPromise()
    .then(data => console.log("Simple promise:",data))
    .catch(error => console.error(`Error catched ${error}`));

// Promises compound: Promise.all
const promise1 = getDataWithPromise();
promise1.then(data => console.log("promise1 ends:",data));
const promise2 = getDataWithPromise();
promise2.then(data => console.log("promise2 ends:",data));
const promise3 = getDataWithPromise();
promise3.then(data => console.log("promise3 ends:",data));
const promise4 = getDataWithPromise();
promise4.then(data => console.log("promise4 ends:",data));
const promise5 = getDataWithPromise();
promise5.then(data => console.log("promise5 ends:",data));

Promise.all([promise1,promise2,promise3,promise4,promise5])
    .then(data => console.log("Promise all ends !!",data));

希望对您有所帮助

您将遇到闭包和 var 变量捕获问题。

您可能想要更改 var 以让 let 在闭包中捕获正确的值,这样 url[jsonCount] 实际上就是您想要的。

而且我认为在一行中做类似的事情会容易得多:)

let results = [];
for(let i = 0; i < urls.length; ++i) results.push(await (await fetch[urls[i]]).json());

这是 map 的一个很好的用途,将 url 映射到 promises...

function fetchUrls(urls) {
  let promises = urls.map(url => fetch(url))
  return Promise.all(promises).then(results => {
    return results.map(result => result.json())
  })
}}

// url is your array of urls (which would be better named as a plural)
fetchUrls(url).then(results => {
  // results will be the fetched json
})

使用async/await语法(等价意义)

// this can be called with await from within another async function
async function fetchUrls(urls) {
  let promises = urls.map(url => fetch(url))
  let results = await Promise.all(promises)
  return results.map(result => result.json())
}

您可以使用 .map 作为循环。但不要使用 new Promise。当 fetch 已经为您提供时,您不需要新的承诺。 另外,将数组命名为 urls 而不是 url。复数可以很好地表明代码的 reader 实际上是 URL 的集合。

这是它的样子:

let fetchJson = url => fetch(url).then(response => response.json());

Promise.all(urls.map(fetchJson)).then(arr => {
    // process your data
    for (let obj of arr) {
        console.log(obj);
    }
});