nodejs从url同步下载图像



我正在尝试构建一个小节点应用程序,它调用一个api,返回指向图像blob png文件的url数组。

然后我试图循环数组并使用实用程序函数下载文件。我需要它同步工作。下载完成后,我想启动一个附加函数。

我从这里开始使用一些异步代码:https://sabe.io/blog/node-download-image

我的utils文件中的异步代码是这样的:

import { promises as fs } from "fs";
import fetch from "node-fetch";
const downloadFile = async (url, path, cb) => {
const response = await fetch(url);
const blob = await response.blob();
const arrayBuffer = await blob.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
fs.writeFile(path, buffer);
cb();
}
export { downloadFile };

我已经尝试使用以下代码将其转换为纯同步:

import fs from "fs";
import fetch from "node-fetch";
const downloadFile = (url, path, cb) => {
const response = fetch(url);
const blob = response.blob();
const arrayBuffer = await blob.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
fs.writeFileSync(path, buffer);
cb();
}
export { downloadFile };

然后在我的index.js文件中,我这样使用它:

import { downloadFile } from './utils/downloadFiles.js';
let imagesArray = [];
let newImageNames = [];
imagesArray.forEach((item, index) => {
const fileName = `${prompt}__${index}_${uuid.v4()}.png`;
const filePath = path.join('src', 'images'); 
newImageNames.push(fileName);
downloadFile(item, filePath, fileDownloadCallback);
});
processDataCallback(); // This is the function which is being fired before the previous downloadFile functions have finished processing.
const fileDownloadCallback = () => {
console.log(`File download callback`);
}

我的图像数组正在填充,看起来像这样的一个例子:

data: [
{
url: 'https://someurl.com/HrwNAzC8YW/A%3D'
},
{
url: 'https://someurl.com/rGL7UeTeWTfhAuLWPg%3D'
},
{
url: 'https://someurl.com/xSKR36gCdOI3/tofbQrR8YTlN6W89DI%3D'
},
{
url: 'https://someurl.com/2y9cgRWkH9Ff0%3D'
}
]

当我尝试使用同步方法时,我得到这个错误TypeError: response.blob is not a function。此函数在异步使用时确实可以工作,但在图像下载完成之前,它会触发我的下一个函数。

我尝试了几次迭代,首先使用createWriteStreamcreateWriteStreamSync(我认为已弃用)。所以换成了fileWrite。我还尝试在async函数内使用同步fileWriteSync,但仍然没有骰子。另一个问题是取回是异步工作的,所以我仍然不知道如何将其连接到只能同步工作。我也想知道如果我可以链then到我的fileDownload util函数的末尾。

我所有的代码是在github,所以我可以共享一个url,如果需要。如果需要,请要求更多的解释。

在Node中是否有等同于jsfiddle的东西?如果是这样的话,我非常乐意尝试做一个演示。

任何帮助都非常感谢。

我们可以保留原来的异步downloadFile直到单独使用(尽管那里有一点改进的空间)。

在索引文件…

import { downloadFile } from './utils/downloadFiles.js';
let imagesArray = [];
let newImageNames = [];
// I'm a little confused about how we get anything out of iterating an empty array
// but presuming it get's filled with URLs somehow...
const promises = imagesArray.map((item, index) => {
const fileName = `${prompt}__${index}_${uuid.v4()}.png`;
const filePath = path.join('src', 'images'); 
newImageNames.push(fileName);
// we can use the callback for progress, but we care about finishing all
return downloadFile(item, filePath, () => {
console.log('just wrote', filePath);
});
});
Promise.all(promises).then(() => {
console.log('all done')
})

Array.forEach不支持异步代码。

将您的代码转换为for...offor代码,它将工作。

。你不能在async/await代码中使用回调。

你的代码看起来像这样:

let index = 0;
for(const item of imageArray) => {
const fileName = `${prompt}__${index}_${uuid.v4()}.png`;
const filePath = path.join('src', 'images'); 
newImageNames.push(fileName);
downloadFile(item, filePath);
fileDownloadCallback();
index++;
});

最新更新