节点Async / Await / Promise.All不等待其他人完成

时间:2019-04-30 21:34:21

标签: javascript node.js promise async-await

我有3个功能需要依次运行,一个功能需要在其他功能运行之前完成,所以我做到了:

var fs = require('fs');

async function create() {

    fs.writeFile('newfile.txt', 'some text here', (err) => {
        if (err) throw err;
        console.log('File is created successfully.');
        return ('File is created successfully.');
    }); 

}

async function waitt() {
    setTimeout(() => { return 'waited!' }, 10000);
}

async function read() {

    fs.readFile('newfile.txt', {encoding: 'utf-8'}, (err,data) => {
        if (!err) {
            console.log('received data: ' + data);
            return ('received data: ' + data);
        } else {
            console.log(err);
        }
    });

}

async function process() {

    let [r1, r2, r3] = await Promise.all([create(), waitt(), read()]);

    console.log(r1 + ' ' + r2 + ' ' + r3);

}


process();

因此,process()运行create()创建一个文件,然后运行waitt()只是暂停,最后read()显示文件的内容。

我遇到的问题是它按此顺序运行:

create()
read()
and then waitt()

代替

create()
waitt()
read()

这就是我想要的。

我该如何解决?

2 个答案:

答案 0 :(得分:2)

这行不通:

async function waitt() {
  setTimeout(() => { return 'waited!' }, 10000);
}

因为,您是在return回调函数中setTimeout,而不是带有async标记的wait函数。

要混合使用回调样式代码和异步/等待,必须先将回调样式代码转换为使用Promises或使用fs-extra,后者已经提供了fs返回承诺的函数。

类似这样的东西:

function waitt() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('waited...')
    }, 10000)
  })
}

其余功能也是如此。

还要注意,如果函数显式返回Promise,则无需将其标记为async即可等待,因为await本质上与Promises一起使用。

现在订购:

Promise.all不保证顺序,因为您可能可以摆脱简单的for..of,或者直接调用函数。

function wait() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('waited...')
      resolve('foo')
    }, 500)
  })
}

// Assume this is your promisified read function.
function read() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('read...')
      resolve('bar')
    }, 500)
  })
}

// Assume this is your promisified create function.
function create() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('created...')
      resolve('baz')
    }, 500)
  })
}

;(async () => {
  try {
    await create()
    await wait()
    await read()
  } catch (err) {
    console.error(err)
  }
})()

答案 1 :(得分:-1)

您的问题是Promise.all不能保证处理顺序,只是列表中的所有promise都已处理。

你不能只说:

await create();
await read();
await waitt();