异步功能按顺序运行,为什么?

时间:2019-12-09 16:41:55

标签: javascript promise async-await es6-promise

我对异步功能有些困惑。它说他们回报了诺言。通常,promise不会立即在其余代码之前运行,因为javascript可以使用“运行到完成”方法。

但是如果异步函数返回一个Promise,您如何解释呢?


const _prefixJS = async file => {
  console.log('running...')
  fs.copyFileSync(file, `${file}.bak`);
  const content = fs.readFileSync(file, 'utf8');
  // Some modifications...
  fs.writeFileSync(file, newContent);
  console.log('stopping!')
};

console.log('start')
_prefixJS(f);
console.log('end')

// Output: start > running... > stopping! > end

我认为输出应为:start > end > starting... > stopping!

因为promise同时运行,并且它们被放置在事件循环的末尾。

我知道这些方法仍然是同步的,但这不是主题。我目前正在从同步的nodejs方法转到异步的方法。我只是问,如果异步方法返回一个Promise,它如何在end console.log语句之前运行?

1 个答案:

答案 0 :(得分:5)

  

但是如果异步函数返回一个Promise,您如何解释呢?

async函数同步运行,直到第一个awaitreturn(包括隐式返回)。 (当我说“直到”时,同步部分包括awaitreturn右侧的操作数。)在这一点(awaitreturn),它返回承诺。这样一来,它可以启动它应该启动的任何异步过程。规范here中对此进行了介绍。

您的_prefixJS不包含任何awaitreturn,因此它同步运行到最后,返回一个承诺,该承诺将用值undefined来实现

要使您的async函数实际上可以异步工作,您需要使用这些函数的fs.promises版本及其await的结果。像这样(未经测试):

const fsp = require("fs").promises;
// ...
const _prefixJS = async file => {
  console.log('running...');
  await fsp.copyFile(file, `${file}.bak`);
  const content = await fsp.readFile(file, 'utf8');
  // Some modifications...
  await fsp.writeFile(file, newContent);
  console.log('stopping!');
};

使用该函数,在调用console.log('running');时,将同时完成fsp.copyFile(...)调用和_prefixJS调用,然后该函数返回其诺言并等待{{1} },然后异步继续其逻辑。

使用占位符用于fsp.copyFile(...)函数的实时示例:

fsp