2017-10-27 13 views
3

私のタスクにnode.jsが選ばれました。公式のGoogle APIクライアントライブラリを持っていて、JSONを使うのが自然です。しかし、私は非同期奇形腫に苦しんでおり、私がインターネットで見つけたガイドは私のケースをカバーしていません。node.jsで非同期で複数のリターンを処理する

ので、この例では、私は2つのファイルの内容を読み、メソッドに渡すしようとしている:私は最初の位置にある2つのコールバックをやっているので、

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

は明らかにそれが働いていません。しかし、2つのメソッドを非同期的に実行し、両方の結果をハンドリングメソッドに渡してから、これが完了した後にさらに進める正しい方法(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

+1

はあなたが約束に見たことがを - HTTPS:/あなたは、複数のコールバックを処理する「のNode.js方法」を参照してくださいを見てみたい場合/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – 23k

+0

は、私はまた、約束を好む一方で'async' npmモジュール:http://caolan.github.io/async/ –

答えて

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 */) 

あなたはMDN ES6 Promiseに約束するための構文を見てする必要があります。

それはのようになりたい、あなたの読み込みのいずれかを「promisify」するには、次の人生はさらに簡単にするために

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

を、あなた「promisifying」自動のためのAPIを提供しbluebirdのようなものを、使用することができますものは、など

docsでも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); 
}); 
+1

Node> = 8.Xには、カスタムコードの記述や外部関数の使用を避けるための「util.promisify」が組み込まれています(https://nodejs.org/api/util.html#util_util_promisify_original)。 –

1

あなたがコールバックを使用する場合は、非同期ライブラリ試してください:特にasync.parallel https://github.com/caolan/async

:詳細については、こちらを

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

関連する問題