使用async / await在fs.writeFile之后执行代码

时间:2018-06-03 15:51:51

标签: javascript node.js async-await

我有一个函数startSurvey,在运行时会检查.json文件中是否存在问题。如果没有问题,它会从Typeform中提取一些问题,并使用saveForm将它们写入.json文件。在写完之后,我想继续执行一些读取.json文件并记录其内容的代码。现在,await saveForm()永远无法解决。

我已经宣传了fs.readFile和fs.writeFile函数。

//typeform-getter.js

const fs = require('fs')
const util = require('util')
const fetch = require('cross-fetch')
require('dotenv').config()

const conf = require('../../private/conf.json')
const typeformToken = conf.tokens.typeform

const writeFile = util.promisify(fs.writeFile)

const getForm = async () => {
  const form = await fetch(`https://api.typeform.com/forms/${process.env.FORM_ID}`, {
    headers: {
      "Authorization": `bearer ${typeformToken}`
    }
  }).then(res => res.json())
  const fields = form.fields
  return fields
}

const saveForm = async () => {
  const form = await getForm()
  return writeFile(__dirname + '/../data/questions.json', JSON.stringify(form))
    .then((e) => {
      if (e) console.error(e)
      else console.log('questions saved')
      return
    })
}


module.exports = saveForm

//controller.js

const fs = require('fs')
const util = require('util')
const request = require('request')
require('dotenv').config()

const typeformGetter = require('./functions/typeform-getter')

const readFile = util.promisify(fs.readFile)
const saveForm = util.promisify(typeformGetter)

let counter = 1
const data = []

const getQuestions = async() => {
  console.log('called')
  try {
    let data = await readFile(__dirname + '/data/questions.json')
    data = JSON.parse(data)
    return data
  } catch (e) {
    console.error('error getting questions from read file', e)
  }
}

const startSurvey = async (ctx) => {
  try {
    const questions = await getQuestions()
    if (!questions) await saveForm()
    console.log(questions) //NEVER LOGS
  } catch (error) {
    console.error('error: ', error)
  }
}

startSurvey() //function called

1 个答案:

答案 0 :(得分:1)

我不知道您的确切错误,但您的代码存在多处问题:

您错误地使用了fs.writeFile的默认版本,如果发生错误,承诺将被拒绝,您将无法获得已解决的承诺,并且错误已解决价值,这就是你正在做的事情。 使用path.join代替连接路径。

startSurvey中,您正在使用console.log(questions),但如果questions.json不存在则不会有任何数据,这应该在您第一次运行程序时发生,因为它已填充按saveForm,您可能希望在saveForm

中返回问题

所以saveForm应该是这样的:

const saveForm = async () => {
    const form = await getForm();
    const filePath = path.join(path.__dirname, '..', 'data', 'questions.json');
    await writeFile(filePath, JSON.stringify(form));

    console.log('questions saved');

    return form;          
 }

startSurvey

const startSurvey = async (ctx) => {
  try {
    const questions = await getQuestions() || await saveForm();
    // This will be logged, unless saveForm rejects
    // In your code getQuestions always resolves
    console.log(questions); 
  } catch (error) {
    console.error('error: ', error)
  }
}

在您的 controller.js 中,当util.promisify已经是承诺时,您正在使用saveForm

所以它应该是:

const saveForm = require('./functions/typeform-getter')