2016-08-06 26 views
0

こんにちは私はここでちょっと変わったことをしようとしています。現在、配列から3人のユーザーのために実行され、次に、配列内のユーザー名の全長に対してこれを実行する方法を終了しますか?非同期/同期ループNode.js

var i = 0, 
fs = require('fs'), 
fetch = require('node-fetch'); 

fs.readFile('file.txt', function(err, data) { 
    var array = data.toString().split("\n"); 
    getCreationDate(array); 
}); 

function getCreationDate(array) { 
    fetch('http://mytwitterbirthday.com/api/?screen_name=' + array[i]) 
    .then(function(res) { 
    return res.json(); 
    }).then(function(json) { 
    console.log(i, array[i]) 
    console.log(json[0].screen_name, json[0].created_at); 
    }).then(function() { 
    i++; 
    getCreationDate(array); 
    }) 
} 

答えて

0

出力と同じ順序で出力する必要はないと仮定します。この場合、getCreationDate()を変更して、単一の名前とそのインデックスを受け入れることができます。

function getCreationDate(name, i) { 
    fetch('http://mytwitterbirthday.com/api/?screen_name=' + name) 
    .then(function(res) { 
    var json = res.json(); 
    console.log(i, name) 
    console.log(json[0].screen_name, json[0].created_at); 
    }); 
} 

ここで、配列の各項目に対して上記の関数を呼び出します。

array.forEach(getCreationDate); 
+0

注:これにより、すべてのリクエストが一度に(パラレルで - レート制限の問題であれば元のコードはシリアルに実行していましたが)、c結果を順番に取得するか、すべての結果がいつ完了するかを知るためには、odeを追加する必要があります。これは実際にはそれだけでは役に立ちません - ソリューションの一部です。 – jfriend00

+0

これは 'Queue consumer'ではなく、一度に各リクエストを実行します。 – Hitmands

+0

@Hitmands:はい、私はその答えに言いました: "私はあなたが出力と同じ順序で出力を印刷する必要はないと仮定します。 – thameera

0

おそらくそれは助けになるかもしれません... あなたはキャッチを見逃しました。

const 
 
    fs = require('fs'), 
 
    fetch = require('node-fetch') 
 
; 
 

 
(new Promise((res, rej) => { 
 
    fs.readFile('file.txt', (err, data) => { 
 
    if(err) { 
 
     return rej(err); 
 
    } 
 
    
 
    return resolve(data.toString().split('\n')); 
 
    }); 
 
})) 
 
    .then(data => doSomething(data, 0)) 
 
    .catch(error => console.error.bind(console)) 
 
; 
 

 
function doSomething(data, index) { 
 
    const API = 'http://mytwitterbirthday.com/api/'; 
 
    const MAX_ERRORS = 3; // or what you want 
 
    let errors = 0; 
 
    
 
    return fetch(`${API}?screen_name=${data[index]}`) 
 
    .then(r => r.json()) 
 
    .then(response => { 
 
     console.log("response", response); 
 
    }) 
 
    .then(() => doSomething(data, ++index)) 
 
    .catch(error => { 
 
     if(MAX_ERRORS <= errors) { 
 
     console.log('giving up', {errors}); 
 
     return; 
 
     } 
 
     
 
     errors += 1; 
 
     return doSomething(data, index); 
 
    }) 
 
    ; 
 
};

0

受け入れ答えは以下を提供していないので、私は別の答えを追加します。

  1. 通知をすべての要求が行われたときに
  2. が順番
  3. に結果を提供
  4. エラー処理
  5. 同時に実行するリクエスト数を決定する同時実行制御

この第1の解決策は、事実を大幅に簡略化するため、Bluebird約束ライブラリを使用します。特に、同時実行制御のために:さえずりが一度にすべての要求を送信すると罰金であれば、

const fs = require('fs'); 
const fetch = require('node-fetch); 

// promisify readFile 
fs.readFileAsync = function(file, options) { 
    return new Promise(function(resolve, reject) { 
     fs.readFile(file, options, function(err, data) { 
      if (err) return reject(err); 
      resolve(data); 
     }); 
    }); 
} 

function getSingleCreationDate(item) { 
    return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) { 
     return response.json(); 
    }); 
} 

function getAllCreationDates(file) { 
    return fs.readFileAsync(file).then(function(data) { 
     let array = data.toString().split("\n"); 
     let results = []; 
     return array.reduce(function(p, item) { 
      return p.then(function() { 
       return getSingleCreationDate(item).then(function(twitterData) { 
        results.push(twitterData); 
       }); 
      }) 
     }, Promise.resolve()).then(function() { 
      // make array of results be the resolved value 
      return results; 
     }); 
    }); 
} 

getAllCreationDates('file.txt').then(function(results) { 
    // process array of results here (in order) 
}).catch(function(err) { 
    // handle error here 
}); 

または:

const Promise = require('bluebird'); 
const fs = Promise.promsifyAll(require('fs')); 
const fetch = require('node-fetch); 

function getSingleCreationDate(item) { 
    return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) { 
     return response.json(); 
    }); 
} 

function getAllCreationDates(file) { 
    return fs.readFileAsync(file).then(function(data) { 
     let array = data.toString().split("\n"); 
     // put whatever concurrency value here works best, higher is more parallelism 
     // lower is more protection from being rate limited by the host 
     return Promise.map(array, getSingleCreationDate, {concurrency: 4}); 
    }); 
} 

getAllCreationDates('file.txt').then(function(results) { 
    // process array of results here (in order) 
}).catch(function(err) { 
    // handle error here 
}); 

この第2の解決策は、標準ES6の約束を使用して、OPの元のコードのような要求をシリアライズ

const fs = require('fs'); 
const fetch = require('node-fetch); 

// promisify readFile 
fs.readFileAsync = function(file, options) { 
    return new Promise(function(resolve, reject) { 
     fs.readFile(file, options, function(err, data) { 
      if (err) return reject(err); 
      resolve(data); 
     }); 
    }); 
} 

function getSingleCreationDate(item) { 
    return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) { 
     return response.json(); 
    }); 
} 

function getAllCreationDates(file) { 
    return fs.readFileAsync(file).then(function(data) { 
     let array = data.toString().split("\n"); 
     return Promise.all(array.map(function(item) { 
      return getSingleCreationDate(item); 
     })); 
    }); 
} 

getAllCreationDates('file.txt').then(function(results) { 
    // process array of results here (in order) 
}).catch(function(err) { 
    // handle error here 
});