在node.js中异步处理多个返回

And*_*ler 3 javascript asynchronous node.js

我为我的任务选择了node.js,因为它有官方的Google API客户端库,并且可以自然地使用JSON.但是我正在努力应对异步的idioma,而我在互联网上发现的指南并没有涵盖我的情况.

所以,在这个例子中,我试图读取两个文件的内容并将它们传递给一个方法:

var fs = require('fs');

// Some more unrelated vars here

function readFiles(callback) {
        fs.readFile('./refresh_token', 'utf8', function(err,refreshToken) {
            if (err) throw err;
            callback(refreshToken);
        });

        fs.readFile('./access_token', 'utf8', function(err,accessToken) {
            if (err) throw err;
            callback(accessToken);
        });
};

function handleResults(refreshToken, accessToken) {
    oauth2Client.setCredentials({
        refresh_token: refreshToken,
        access_token: accessToken
    });
    proceedNext(oauth2Client);
};

function proceedNext(credentialsObject) {
    // do some more job
};

readFiles(handleResults);
Run Code Online (Sandbox Code Playgroud)

显然它不起作用,因为我在第一个位置做了两次回调.但是,以异步方式执行两个方法的正确方法(node.js方式)是什么,将两个结果传递给处理方法,然后只有在完成之后才继续进行?

我试过这样的事情:

function readFiles() {
        fs.readFile('./refresh_token', 'utf8', function(err,refreshToken) {
            if (err) throw err;

            fs.readFile('./access_token', 'utf8', function(err,accessToken) {
                if (err) throw err;

                oauth2Client.setCredentials({
                    refresh_token: refreshToken,
                    access_token: accessToken
                });

                proceedNext();
            });
        });
};
Run Code Online (Sandbox Code Playgroud)

它在使用全局变量之后起作用,但我认为这是一个可怕的,可怕的想法,它破坏了node.js的观点.我正在寻找一种正确的方法来做到这一点,我觉得在通过这个墙之后,其他一切应该在node.js中开始有意义了.

Jos*_*eam 5

在高级别,您可以并行启动2个承诺,只有在两个承诺都解决后才能解决:

Promise.all([
  new Promise((resolve, reject) => { /* your first fs read */ }),
  new Promise((resolve, reject) => { /* your second fs read */ })
]).then(result => {
  const refreshToken = result[0]
  const accessToken = result[1]

  // do more stuff
})
.catch(err => /* handle error */)
Run Code Online (Sandbox Code Playgroud)

您需要查看MDN ES6中Promise promises的语法.

为了"宣传"你的一个读物,它看起来像:

new Promise((resolve, reject) => {
  fs.readFile('./refresh_token', 'utf8', function(err, refreshToken) {
    if (err) {
      reject(err)
    }
    resolve(refreshToken)
  })
})
Run Code Online (Sandbox Code Playgroud)

为了让生活更简单,你可以使用像bluebird这样的东西,它提供自动"宣传"东西的API等.

文档甚至显示本作fs:

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require("fs"));

fs.readFileAsync("myfile.js", "utf8").then(function(contents) {
    console.log(contents);
}).catch(function(e) {
    console.error(e.stack);
});
Run Code Online (Sandbox Code Playgroud)