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

标签 javascript node.js async-await

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

我已经 promise 了 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

最佳答案

我不知道您的确切错误,但您的代码有多个问题:

您错误地使用了 fs.writeFile 的 promisified 版本,如果发生错误, promise 将被拒绝,您将无法获得已解决的 promise 错误作为解析值,这就是您正在做的事情。 使用 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;          
 }

开始调查

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 中,您在 saveForm 上使用 util.promisify(当它已经是一个 promise 时)。

所以应该是:

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

关于javascript - 使用 async/await 在 fs.writeFile 之后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50668219/

相关文章:

javascript - eBay API - 保护 JavaScript 应用程序中的 AppID

javascript - 如何使用 bokeh 和 javascript 旋转 2D 笛卡尔图?

c# - Azure Functions v1 中的 HTTP 触发器如何返回异步堆栈跟踪?

c# - RunAsync - 如何等待 UI 线程上的工作完成?

javascript - 让复选框过滤器正常工作

javascript - 谷歌云函数 JS 错误 : Cannot convert undefined or null to object

node.js - Node 不需要 *.coffee 文件

javascript - 在 Array.map 函数中使用 await

javascript - 在将 groupby 与 Sequelize 和 SQLite 结合使用时,如何获取等于某个值的行数?

javascript - 在 async.auto 链中使用 async/await 会导致 TypeError : callback is not a function