2017-02-17 3 views
0

learnyounodeからこのエクササイズを完了しました。私はES2015の約束(またはもっと簡単な場合は他のライブラリ)を使ってリファクタリングしようとしています。私は約束を読んだことがあります。私はそれがどのように機能するのか理解していると思いますが、次のコードでそれを使用することができるかどうか、またその方法を知りたいと思います。コールバックの代わりに約束を使用

私の目標は、コードを読みやすく理解しやすくすること、そしてプロセスの約束をより良く理解することです。 、

'use strict'; 
 

 
const http = require('http'); 
 
if (process.argv.length != 5) { 
 
    throw new Error('Please provide the 3 URLs as a command line arguments'); 
 
} 
 

 
let urls = []; 
 
for (let i = 2; i < process.argv.length; i++) { 
 
    urls.push(process.argv[i]); 
 
} 
 

 
function httpGet(url) { 
 
    let result = ''; 
 
    return new Promise((resolve, reject) => { 
 
     http.get(url, function (res) { 
 
      res.on('error', err => { 
 
       reject(err); 
 
      }); 
 
      res.on('data', data => { 
 
       result += data; 
 
      }); 
 
      res.on('end',() => { 
 
       //You can do resolve(result) if you don't need the url. 
 
       resolve({url, result}); 
 
      }); 
 
     }) 
 
    }); 
 
} 
 

 
let promises = urls.map(url => httpGet(url)); 
 

 
Promise.all(promises) 
 
    .then(results => { 
 
     console.log(`All done. Results: ${results}`); 
 
    }) 
 
    .catch(err => { 
 
     console.error(err); 
 
    });

+1

[ドキュメント](https://nodejs.org/api/http.html#http_http_get_options_callback)によると、 'http.get'は約束を返しません。コールバックメソッドのみをサポートします。あなたは自分自身で約束を作り、解決しなければなりません。 – Cristy

+0

bluebirdsはどのように上記コードの助けを約束しますか?*回答:まったく* –

答えて

2

あなたはこのような何かを試みることができます与えられた入力の順序。

編集:これは、指定された順序でデータを出力するようになりました。

const http = require('http'); 

if (process.argv.length != 5) 
    throw new Error("Please provide the 3 URLs as a command line arguments"); 

let urls = []; 
let results = []; 
let count = 0; 

for (let i = 2; i < process.argv.length; i++) 
    urls.push(process.argv[i]); 

function httpGet (url) 
{ 
    return new Promise((resolve, reject) => { 
     let result = ''; 
     http.get(url, res => { 
      res.on('data', data => result += data); 
      res.on('end',() => resolve(result)) 
     }).on('err', reject); 

    }); 
} 

function printResults() { 
    for (let result of results) { 
     console.log(result); 
    } 
} 

for (let i = 0; i < urls.length; i++) { 
    httpGet(urls[i]) 
     .then(result => { 
      results[i] = result; 
      if (++count === 3) 
       printResults(); 
     }) 
     .catch(err => console.log(err)); 
} 
+0

ありがとう、それは完全に動作します – Noxxys

1

あなたはこのような何かを行うことができをしかし、あなたは結果がで、返却されない可能性があることに注意する必要があります。

let http = require("http"); 

if (process.argv.length != 5) { 
    throw new Error("Please provide the 3 URLs as a command line arguments"); 
} 

let urls = []; 
let results = []; 
let count = 0; 

for (let i = 2; i < process.argv.length; i++) { 
    urls.push(process.argv[i]); 
} 

function httpGet(index) { 
    let url = urls[index]; 
    let result = ""; 

    http.get(url, res => { 
     res.on("data", data => { 
      result += data; 
     }); 

     res.on('end',() => { 
      count += 1; 
      results[index] = result; 

      if (count === 3) { 
       results.forEach(function(result) { 
        console.log(result); 
       }); 
      } 
     }); 
    }); 

} 

for (let i = 0; i < urls.length; i++) { 
    httpGet(i); 
} 
+0

ありがとう。それは動作しますが、実際にはURLの順序を保持しません。 'httpGet(index)'にインデックスを渡して、以前のように結果を 'results [index]'に保存することで、注文を保存することができました。 – Noxxys

+0

@Noxxysインデックスに関数を渡す理由を見落としてしまったようですが、それに対応するために答えを更新するかもしれません。 –

+0

編集ありがとうございました – Noxxys

0

ノードのコアライブラリのインターフェイスは、プロミスベースではありません。ただし、単純な関数を使用して、ノードスタイルのコールバックを受け入れる関数を約束を返す関数に変換することができます。あなた自身で書くことは良い運動かもしれません。またはnpmでそれを見つける。この変換関数は通常promisifyと名付けられています。より高度なバージョンでは、オブジェクトを取り込み、すべてのメソッドを変換します。

+3

すばやくご検討ください。 http.getはエラー優先の規則に従いません。 'res'は最初の引数です。したがって、例えばbluebird.promisifyはそのままでは動作しません。 –

1

それは教育目的のために約束ロジックのすべてを自分で実装するのに有用であるかもしれないが、約束でHTTPリクエストのための良好なモジュールがあることに留意すべきではrequest-promiseのように、サポートしています。

毎月100万回以上ダウンロードされており、広く使用されており、この種のタスクのテスト済みソリューションです。そして、私は常にホイールを再発明するのではなく、実際の作業に適したテスト済みのソリューションを使用することをお勧めします。

今のところ、教育目的のために、できる限り多くの車輪を再発明することを常にお勧めします。例えば、約束にコールバックベースのコードを変換するいくつかの例については、この答えを参照してください。

もこの答えからのすべてのリンクを参照してください。

コールバックと約束を使って、同じコードの例をたくさん見つけることができます。あなたは違いを調べることができます。

+0

ありがとう、私はこれらのリンクを読んで、要求約束を使用しようとします – Noxxys

関連する問題