将async / await与setTimeout函数

时间:2018-02-08 11:12:24

标签: node.js asynchronous async-await settimeout es6-promise

我正在尝试从网站下载文件,并希望使用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);
}

1 个答案:

答案 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);