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

Javascript 在node.js中异步处理多个返回,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我选择node.js来完成我的任务,因为它有官方的GoogleAPI客户端库,可以很自然地使用JSON。但我正在努力学习异步习语,而我在互联网上找到的指南并没有涵盖我的情况 因此,在本例中,我尝试读取两个文件的内容并将其传递给一个方法: var fs = require('fs'); // Some more unrelated vars here function readFiles(callback) { fs.readFile('./refresh_token', 'u

我选择node.js来完成我的任务,因为它有官方的GoogleAPI客户端库,可以很自然地使用JSON。但我正在努力学习异步习语,而我在互联网上找到的指南并没有涵盖我的情况

因此,在本例中,我尝试读取两个文件的内容并将其传递给一个方法:

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);
显然,这不起作用,因为我在第一个职位上做了两次回访。但是,异步执行两个方法的正确方式(node.js方式)是什么,将这两个结果都传递给handling方法,然后仅在完成后继续

我试过这样的方法:

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();
            });
        });
};

在玩了一点全局变量之后它就工作了,但我认为这是一个非常糟糕的想法,它破坏了node.js的意义。我正在寻找一种正确的方法来做到这一点,我觉得在通过这堵墙之后,node.js中的其他一切都应该开始有意义了。在高层次上,您可以并行启动两个承诺,并且只有当它们都已解决时才能解决:

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 */)
您需要查看中承诺的语法

要“允诺”你的一篇文章,它看起来像:

new Promise((resolve, reject) => {
  fs.readFile('./refresh_token', 'utf8', function(err, refreshToken) {
    if (err) {
      reject(err)
    }
    resolve(refreshToken)
  })
})
为了使生活更简单,您可以使用类似的东西,它为自动“承诺”的东西提供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);
});

如果您喜欢使用回调,请尝试异步库:

特别是async.parallel:

const async = require('async');

async.parallel({
    refreshToken: function(callback) { 
        fs.readFile('./refresh_token', 'utf8', function(err,refreshToken) {
            if (err) throw err;
            callback(null, refreshToken);
        });
    },
    accessToken: function(callback) { 
        fs.readFile('./access_token', 'utf8', function(err,accessToken) {
            if (err) throw err;
            callback(null, accessToken);
        });
    }
}, function(err, results) {
     // results is now equals to: {refreshToken: "...", accessToken: "..."}
});

查看此处了解更多信息:

您是否研究过承诺?虽然我也更喜欢承诺,但如果您想了解处理多个回调的“node.js方式”,请查看
async
npm模块:node>=8.X具有内置的
util.promisify
,它使您无需编写自定义代码或使用外部命令,