async函数返回Promise {<pending>}?

时间:2017-05-16 23:03:30

标签: javascript node.js asynchronous promise

我有以下异步功能:

async function readFile () {
  let content = await new Promise((resolve, reject) => {
    fs.readFile('./file.txt', function (err, content) {
      if (err) {
        return reject(err)
      }
      resolve(content)
    })
  })

  console.log(content)
}

readFile()

运行得很好。它按预期将文件缓冲区输出到控制台。但现在,如果我尝试返回值:

async function readFile () {
  let content = await new Promise((resolve, reject) => {
    fs.readFile('./file.txt', function (err, content) {
      if (err) {
        return reject(err)
      }
      resolve(content)
    })
  })

  return content
}

console.log(readFile())

我现在得到:

Promise { <pending> }

这是为什么?为什么你可以在该函数中使用一个值但是当你将它从函数中返回时它现在是一个Promise?

您如何在正常的工作流程中实际使用它?例如,假设我想检查文件是否存在,然后读入文件,然后用内容更新一些数据库,同步伪代码看起来像这样:

if (fileExists(path)) {
  buffer = readFile(path)
  updateDatabase(buffer)
}

该工作流程包含3个单独的异步操作。你会怎样用async/await做这样的事情?是否必须将整个脚本包含在async函数中?

async function doSomething () {
  if (fileExists(path)) {
    buffer = readFile(path)
    updateDatabase(buffer)
  }
}

(请记住,这只是伪代码,但希望它能解决我的问题。)

1 个答案:

答案 0 :(得分:6)

所有async函数都会返回评论中提到的承诺。因此,您可以重写这样的readFile函数:

function readFile() {
  return new Promise((resolve, reject) => {
    fs.readFile('./file.txt', function (err, content) {
      if (err) {
        return reject(err)
      }
      resolve(content)
    })
  })
}

然后,您将通过readFile消费await的返回值:

console.log(await readFile()) // will log your actual file contents.

此范例的常用工作流程是将异步操作分解为各自返回承诺的单独函数,然后在更广泛的async函数内运行它们,与您的建议非常相似,但使用{{1}和s一样的错误处理:

await