在async await周围写一个循环来并行读写文件?

时间:2017-02-07 23:42:21

标签: node.js asynchronous async-await phantomjs

我正在使用fsphantomJS

const phantom = require('phantom');
const fs = require('fs');

我从幻影JS打开了 4条路线(网址)。打开时,会读取页面内容,然后node.fs会将该内容写入其自己的html文件中。

const routes = [
  'about',
  'home',
  'todo',
  'lazy',
]

问题:

如何为const routes中的每个值并行循环此异步函数。

(async function() {
  const instance = await phantom.create();
  const page = await instance.createPage();
  const status = await page.open(`http://localhost:3000/${routes}`);
  const content = await page.property('content');

  await fsPromise(`${routes}.html`, content);

  await instance.exit();
}());

const fsPromise = (file, str) => {
  return new Promise((resolve, reject) => {
    fs.writeFile(file, str, function (err) {
      if (err) return reject(err);
      resolve(`${routes} > ${routes}.html`);
    });
  })
};

1 个答案:

答案 0 :(得分:1)

我需要一段时间才能在支持awaitasync的环境中实现此功能。事实证明,Node v7.5.0支持它们 - 比与babel战斗更简单!在这次调查中唯一的另一个问题是我用来测试request-promise,当承诺没有正确构建时,似乎没有优雅地失败。当我尝试使用await时,我看到了很多这样的错误:

return await request.get(options).map(json => json.full_name + ' ' + json.stargazers_count);
                 ^^^^^^^
SyntaxError: Unexpected identifier

最后,我意识到你的promise函数实际上并没有使用async / await(这就是为什么我的错误),所以前提应该是一样的。这是我工作的测试 - 它与你的非常相似。关键在于同步for()迭代:

var request = require('request-promise')
var headers = { 'User-Agent': 'YOUR_GITHUB_USERID' }
var repos = [
    'brandonscript/usergrid-nodejs',
    'facebook/react',
    'moment/moment',
    'nodejs/node',
    'lodash/lodash'
]

function requestPromise(options) {
    return new Promise((resolve, reject) => {
        request.get(options).then(json => resolve(json.full_name + ' ' + json.stargazers_count))
    })
}

(async function() {
    for (let repo of repos) {
        let options = {
            url: 'https://api.github.com/repos/' + repo,
            headers: headers,
            qs: {}, // or you can put client_id / client secret here
            json: true
        };
        let info = await requestPromise(options)
        console.log(info)
    }
})()

虽然我无法测试,但我很确定这会起作用:

const routes = [
    'about',
    'home',
    'todo',
    'lazy',
]

(async function() {
    for (let route of routes) {
        const instance = await phantom.create();
        const page = await instance.createPage();
        const status = await page.open(`http://localhost:3000/${route}`);
        const content = await page.property('content');

        await fsPromise(`${route}.html`, content);

        await instance.exit();
    }
}())

由于您使用的是ES7语法,因此您还应该能够在不声明承诺的情况下执行fsPromise()函数:

async const fsPromise = (file, str) => {
    return await fs.writeFile(file, str)
}