暂停 for 循环直到函数完成

Pause a for loop until function is completed

我一天的大部分时间都在绞尽脑汁,我试图下载多个具有迭代 ID 的文件,我使用 for 循环来迭代并调用调用下载函数的 Web 请求一个文件。

但是,我注意到由于同时请求多个文件,文件往往会损坏,我正在使用以下 NPM 包 https://www.npmjs.com/package/nodejs-file-downloader 它具有许多简洁的功能,并且还基于承诺。

我的问题是我不知道如何对包使用 promises,我希望循环等到文件下载成功的 downloadFile()。

const axios = require('axios');
const url = require('url')
const fs = require('fs');
const DOWNLOAD_DIR = '/'
var downloadCo5mplete = false
const Downloader = require("nodejs-file-downloader");
const sleep = require('sleep-promise');

async function getFile(version)
{

  axios.request({
    url: "https://****.****.com/v1/id/*****/version/" + version,
    method: "get",
    headers:{
        ContentType: 'application/json',
        Accept: "application/json",
        Cookie: ""
    } 
  }).then(function (response) {
      const placeData = response.data.location;
      //if placeData is null, then the version is not available
      if(placeData == null)
      {
        console.log("Version " + version + " not available");
        return;
      }
      console.log("Version " + version + " available");

      downloadFile(version, placeData)
      

  }).catch(function (error) {
      //console.log(error);
  });

}



async function downloadFile(version, data)
{
  const downloader = new Downloader({
    url: data, //If the file name already exists, a new file with the name 200MB1.zip is created.
    directory: "./2506647097", //This folder will be created, if it doesn't exist.
    fileName: "2506647097 - " + version + ".rbxl",
    onError: function (error) {
      //You can also hook into each failed attempt.
      console.log("Error from attempt ", error);
    },
  });
  
  try {
    downloader.download(); //Downloader.download() returns a promise.
    console.log("Downloaded version " + version + " successfully");
  } catch (error) {
    //IMPORTANT: Handle a possible error. An error is thrown in case of network errors, or status codes of 400 and above.
    //Note that if the maxAttempts is set to higher than 1, the error is thrown only if all attempts fail.
    console.log("Download failed", error);
  }
};


async function main()
{
  for(var i = 7990; i < 7995; i++)
  {
    await getFile(i);
  }
}

main()

目前我的控制台在 运行 代码上看起来像这样。

Version 7990 available
Version 7991 available
Version 7992 available
Downloaded version 7990 successfully
Version 7993 available
Downloaded version 7991 successfully
Version 7994 available
Downloaded version 7992 successfully

我希望它看起来像这样。

Version 7990 available
Downloaded version 7990 successfully
Version 7991 available
Downloaded version 7991 successfully
Version 7992 available
Downloaded version 7992 successfully
Version 7993 available
Downloaded version 7993 successfully
Version 7994 available
Downloaded version 7994 successfully

对错误的代码表示歉意,希望有人能帮助我!

-干杯

你应该在你的 axios 请求上使用 await

async function getFile(version)
{

  await axios.request({
    url: "https://****.****.com/v1/id/*****/version/" + version,
    method: "get",
    headers:{
        ContentType: 'application/json',
        Accept: "application/json",
        Cookie: ""
    } 
  }).then(function (response) {
      const placeData = response.data.location;
      //if placeData is null, then the version is not available
      if(placeData == null)
      {
        console.log("Version " + version + " not available");
        return;
      }
      console.log("Version " + version + " available");

      downloadFile(version, placeData)
      

  }).catch(function (error) {
      //console.log(error);
  });

}

None 的函数证明了 async 关键字(如果您不使用 await,则使用 async 是无意义的)。

但是您的所有功能都缺失了 return。您需要 return 您在函数中创建的承诺。

比较 - 每个代码路径都以 return:

结尾
// returns a promise for whatever downloadFile() produces
function getFile(version) {
  return axios.request({ /* ... */ }).then((response) => {
    return downloadFile(version, response.data.location);
  }).catch(err => {
    return {error: "Download failed", version, err};
  });
}

// downloadFile() also returns a promise, so we return that
function downloadFile(version, data) {
  if (version && data) {
    const downloader = new Downloader({ /* ... */ });
    return downloader.download();
  }
  throw new Error("Invalid arguments");
};


// `downloads` will be an array of promises, we can wait for them with `Promise.all()`
function main() {
  const downloads = [];
  for (let i = 7990; i < 7995; i++) {
    downloads.push(getFile(i));
  }
  Promise.all(downloads).then((results) => {
    // all downloads are done
  }).catch(err => {
    console.log(err);
  });
}

您可能不想 daisy-chain 下载。你只想等到一切都完成。 Promise.all() 做到了。