2017-11-16 1 views
0

これを説明する最も簡単な方法は、あなたのすべてのパッケージについてあなたのpackage.jsonを検索しようとしていて、npmレジストリを使って新しい更新があるかどうかを調べることです。私はその大部分をしています。ループのために、次のために受け入れ:反応の複数の約束でこれをどう扱うか分かりません

import request from 'request' 

export const findAllUpdates = (packageInfo) => { 
    for(prop in packageInfo) { 
    request('https://registry.npmjs.org/' + prop, function(err, resp) { 
     json = JSON.parse(resp.body); 

     if (json['dist-tags'].latest !== packageInfo[prop].version) { 
     // Do something, we are not the same version so we should 
     // update some counter. 
     } 
    }); 
    } 
} 

あなたpackageInfoは依存性またはDEV依存package.jsonからとパッケージlock.jsonまたはyarn.lock

のいずれかを表し key=>valueの目的であります

重要な部分は、上記の機能の中でインストールしたものを見ています。その後、レジストリを使ってそのパッケージ情報を取得し、レジストリの最新バージョンとインストールしたものとを比較します。コンポーネントの状態をトータルカウントで更新します。

私たちはコールバックhellを入力したことがあります。特にforループを使用して、すべてのパッケージをループしてリクエストしています。

私は変数を作成して、そこにレスポンスを格納することはできません。なぜなら、要求が行われた後にアクセスできないためです。私はここでイベントを使用する方法を知ることはできません。なぜなら、40個のパッケージをdepまたはdevのいずれかにインストールし、起動するイベントがたくさんあるからです。

最終的には、約束を使用することが適切な解決策であるかもしれませんが、約束のコンセプト全体は、.then(() => {}),.catch(() => {})というコールバックであり、私を正方形に戻します。

目標はコンポーネントでこれを呼び出すと、そのコンポーネントの状態を更新する必要がある(または少なくとも新しいバージョンを持っている)パッケージの総量で更新することです

任意のアイデア?私はこれについてすべて間違っているのですか?

答えて

1

あなたは約束を見ています。

最初に、requestという約束が可能なバージョンを提供することです。 utilには、ノードコールバックスタイルの関数をとり、約束可能なバージョンを返す関数promisifyがあります。だから、:

import util from 'util'; 
// ... 
const prequest = util.promisify(request); 

配列に約束を集める(およびそれらにthenを使用して、あなたのリクエストを行い、その後、(すべてを一度に全体のAPIを行うことができますNPMモジュール、promisifyは、もあります。)後処理を行うには、thenは新しい約束を返しますので、まだ有効です)、Promise.allを使用して、すべてが解決するまで(またはいずれかが拒否されるまで)待ってください。だから、すべて一緒

import request from 'request'; 
import util from 'util'; 

const prequest = util.promisify(request); 

export const findAllUpdates = (packageInfo) => { 
    const updates = [] 
    for (const prop in packageInfo) { 
    updates.push(prequest('https://registry.npmjs.org/' + prop).then(resp => { 
     const json = JSON.parse(resp.body); 

     if (json['dist-tags'].latest !== packageInfo[prop].version) { 
     // Do something, we are not the same version so we should 
     // update some counter. 
     } 

     // Perhaps return something here, it will be the resolution 
     // for the promise for this request; otherwise, the promise 
     // will resolve with `undefined`. 
    })); 
    } 
    return Promise.all(updates); 
}; 

全体的な機能の約束は、それらのいずれかが拒否した場合は拒否(再び)(順)アレイ内の各約束の結果の配列に解決、またはすること。

私はasync/awaitを提案したいと思っていますが、現時点では並行して約束しているものは多くありません。 (await.allの時折の話がありましたが、Promise.allのことをやっていますが、それはまだ捕まっていません。

import request from 'request'; 
import util from 'util'; 

const prequest = util.promisify(request); 

const checkOne = async (prop) => { 
    const resp = await prequest('https://registry.npmjs.org/' + prop); 
    const json = JSON.parse(resp.body); 
    if (json['dist-tags'].latest !== packageInfo[prop].version) { 
    // Do something, we are not the same version so we should 
    // update some counter. 
    } 

    // Perhaps return something here, it will be the resolution 
    // for the promise for this request; otherwise, the promise 
    // will resolve with `undefined`. 
}; 

export const findAllUpdates = (packageInfo) => { 
    const updates = [] 
    for (const prop in packageInfo) { 
    updates.push(checkOne(prop); 
    } 
    return Promise.all(updates); 
}; 

そしてもちろん、packageInfo内のすべてのプロパティが「自分」プロパティである場合:)

は、我々は少し物事を破る場合は、しかし、それはasync/awaitと少し進歩していることを言いましたfindAllUpdatesがずっと簡単なり、(継承されない):

export const findAllUpdates = (packageInfo) => { 
    return Promise.all(Object.keys(packageInfo).map(checkOne)); 
}; 

サイドノート:私はいくつか不足している宣言を追加しましたabov e。

0

私はPromiseの使用をお勧めします。いくつかの非同期呼び出しを行い、Promise.allを使用してそれらを待つことができます。

また、「findAllUpdates」メソッドからPromiseを返すと、情報が利用可能なときに発信者が自分の状態を更新するのは簡単です。それは約束を使用しての下、私は簡単な例を作成しました

findAllUpdates(..) 
    .then(result => this.setState({ 
    packagesNeedUpdate: result.filter(p => !p.latest).length 
    })); 

ではそのようなものだろう反応します。それは要求を偽造しますが、そうでなければかなり正確です。

// Fake requests. Will return version '1.0.0' after one second. 
 
const makeRequest = url => { 
 
    return new Promise(resolve => { 
 
    setTimeout(() => { 
 
     resolve(JSON.stringify({ 
 
     'dist-tags': { 
 
      'latest': '1.0.0' 
 
     } 
 
     }, null, 2)); 
 
    }, 1000); 
 
    }); 
 
} 
 

 
const findAllUpdates = (packageInfo) => { 
 
    return new Promise(resolve => { 
 
    const promises = Object.keys(packageInfo) 
 
     .map(prop => makeRequest('https://registry.npmjs.org/' + prop).then(JSON.parse)); 
 
     
 
    Promise.all(promises) // Wait for all promises 
 
     .then(jsons => { 
 
     const results = Object.keys(packageInfo) 
 
      .map((prop, i) => { 
 
      const latestInNpm = jsons[i]['dist-tags'].latest; 
 
      const current = packageInfo[prop].version 
 
      return { 
 
       prop, 
 
       latest: latestInNpm === current 
 
      } 
 
      }); 
 
     resolve(results); // Return result to caller 
 
     }); 
 
    }); 
 
} 
 

 
function run() { 
 
    console.log('Loading..'); 
 
    
 
    const packages = { 
 
    'react': {version: '0.0.1'}, 
 
    'angular': {version: '1.0.0'}, 
 
    'ember': {version: '0.5.0'}, 
 
    'mithril': {version: '0.9.0'} 
 
    }; 
 
    
 
    findAllUpdates(packages).then(result => { 
 
    const needUpdates = result.filter(p => !p.latest).length; 
 
    console.log('Need updates: ', needUpdates); 
 
    }); 
 
} 
 

 
run();

関連する問題