簡體   English   中英

在node.js中異步處理多個返回

[英]Handling multiple returns asynchronously in 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);

顯然它不起作用,因為我在第一個位置做了兩次回調。 但是,以異步方式執行兩個方法的正確方法(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();
            });
        });
};

它在使用全局變量之后起作用,但我認為這是一個可怕的,可怕的想法,它破壞了node.js的觀點。 我正在尋找一種正確的方法來做到這一點,我覺得在傳遞這個牆之后,其他一切應該在node.js中開始有意義了。

在高級別,您可以並行啟動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 */)

你需要在MDN ES6 Promise查看promises的語法。

為了“宣傳”你的一個讀物,它看起來像:

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

為了讓生活更簡單,你可以使用像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);
});

如果您更喜歡使用回調,請嘗試使用異步庫: https//github.com/caolan/async

特別是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: "..."}
});

點擊此處獲取更多信息: https//caolan.github.io/async/docs.html#parallel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM