我正在尝试从网站下载文件,并希望使用setTimeout在每个请求之间暂停代码1秒。
我有一个stockFile函数循环遍历一个url数组( path 是我在磁盘上存储文件的地方)。这是我的代码(版本A):
async function stockFiles(urls, path) {
_.map(urls, async (elem) => {
await timeOut(1000);
const writableStream = await _createWriteStream(path);
await _getFile(elem, writableStream);
});
}
function timeOut(ms) {
return new Promise((fulfill) => {
setTimeout(fulfill, ms);
});
}
编辑:版本B:
async function stockFiles(urls, path) {
_.map(urls, async (elem) => {
const writableStream = await _createWriteStream(path);
await _getFile(elem, writableStream);
await timeOut(1000);
});
}
function timeOut(ms) {
return new Promise((fulfill) => {
setTimeout(fulfill, ms);
});
}
问题:当我调用stockFiles(版本A)时,它会在发出请求之前暂停,但似乎我在磁盘上同时收到所有文件。我真正想要的是我的代码在每个请求之间暂停,因此每个文件接收之间都有一个延迟。
编辑:当我调用stockFiles(版本B)时,它根本不会暂停执行,并且我同时收到所有文件。
/**************** helpers functions **************/
function _createWriteStream(path) {
return new Promise((fulfill, reject) => {
fs.createWriteStream(path, (err, data) => {
if (err) {
reject(err);
}
fulfill(data);
});
});
}
// I use superagent package to make the request
async function _getFile(url, writableStream) {
await request
.get(url)
.buffer(true).parse(request.parse.image)
.pipe(writableStream);
}
答案 0 :(得分:1)
问题是你正在同时启动所有请求,然后它们都在等待1000毫秒,然后它们都在执行。听起来你已经理解了这一点。你需要做的就是将它们排队,这样每个人只能在前一个完成之后才开始。
尝试将stockFiles功能更改为更像这样的内容:
async function stockFiles(urls, path) {
for (let url of urls) {
const writableStream = await _createWriteStream(path);
await _getFile(elem, writableStream);
await timeOut(1000);
}
}
这是一些完整的示例代码。我测试了它并观察到循环每秒只运行一次迭代(通过观察console.logs可以看出)。
function timeOut(ms) {
return new Promise((fulfill) => {
setTimeout(fulfill, ms);
});
}
async function stockFiles(urls, path) {
for (let url of urls) {
console.log(url);
await timeOut(1000);
}
}
let urls = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
stockFiles(urls);