私は特定のウェブサイトのデータスクレーパーを構築しています。私は10秒ごとに要求を出したいので、私は手動で入力したURLの配列からパラメータとしてurlを受け取るsetTimeoutループとして設定しました。コールバックでは、このurlを要求して応答を解析し、最終的にcsvに変換できるように構造化された新しい配列にデータをプッシュします。私は私の依存関係と一緒に下の完全なコードを貼り付けます。私の非同期コードをsetTimeoutと同期させる。私は約束が必要ですか?
これらの要求の約1/5が未定義として返されるという問題があります。私は、タイムアウト機能がこれを処理し、プログラムが同期して動作すると思っていました。私は明らかに間違っていました。これを調べると、多くの人が非同期リクエストを注文するために約束の依存関係を使用することが分かりました。ここで私の質問:それは必要ですか?または、コールバック/ setTimeoutを調整して、別の依存関係を追加せずに動作させることはできますか?
編集私が、私はこのアプリがやりたい、まさにここにコピーしています明確ではありませんでしたので: 私はプログラムは、要求を取るJSON文字列を返し、データのためのそのJSON文字列を解析したいです、そのデータを配列に追加し、その配列をcsvとしてエクスポートします。私はこの機能をループして長いURLのリストに対して行うことができますが、一度に1つのリクエストを行い、最初のレスポンスから必要なデータが収集されるまで次のリクエストを繰り返すのを待ちます。 10秒ごとにリクエストを送信したいだけです。
は、ここに私のコードです:
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
var arr = [];
var url = //A bunch of urls that I'm leaving out to conserve space
i = 0;
function timeout() {
setTimeout(function() {
request(url[i], function(error, response, html){
if(error){
console.log(error);
} else {
var $ = cheerio.load(html);
var company, industry, size, website, type;
var inArr = [];
$('div .image-wrapper img').filter(function(){
var data = $(this);
company = data.attr('alt');
inArr.push("\"" + company + "\"");
})
$('.industry p').filter(function(){
var data = $(this);
industry = data.text();
inArr.push("\"" + industry + "\"");
})
$('.company-size p').filter(function(){
var data = $(this);
size = data.text();
inArr.push("\"" + size + "\"");
})
$('.website p a').filter(function(){
var data = $(this);
website = data.text();
inArr.push("\"" + website + "\"");
})
$('.type p').filter(function(){
var data = $(this);
type = data.text();
inArr.push("\"" + type + "\"");
})
arr.push(inArr);
console.log("I just sourced data for " + company);
if (i === url.length - 1) {
clearTimeout(timeout);
console.log("All done!")
var csvContent;
arr.forEach(function(infoArray, index){
dataString = infoArray.join(",");
csvContent += index < arr.length ? dataString+ "\n" : dataString;
});
fs.writeFile('output.csv', csvContent, function(err){
console.log('File successfully written! - Check your project directory for the output.csv file');
});
} else {
i++;
timeout();
}
}
});
}, 10000);
};
timeout();
_ "これらの要求のうち約5分の1が未定義として返されるという問題があります。" _ clearTimeout(timeout);の期待される結果は何ですか? 'timeout'関数内の' setTimeout'がintially宣言されていないか、後で 'timeout'変数として設定されていますか? 'timeout'は、質問 – guest271314
で' js'の関数としてのみ定義されています。本当の質問は何ですか?あなたは 'request()'操作を何度も実行しようとしていますか?もしそうなら、 'setTimeout()'でどのくらい時間がかかるかを推測するのは悪い設計です。操作を順序付ける実際のコードを記述する必要があります。しかし、最初に、あなたの 'setTimeout()'の問題ではなく、本当の問題がここにあることを明確にしてください。解決策の試みだけでなく、実際の問題について説明すると、問題解決のための最善の解決策を見つけることができます。 – jfriend00
'clearTimeout(timeout);'は何故か何の意味もありません。 'timeout'はあなたのコード内の関数であり、タイマーIDではありません。 'clearTimeout()'は 'setTimeout()'への呼び出しからの戻り値で動作します。 'var timer = setTimeout(f、t);と同じです。 clearTimeout(タイマー); '。さらに、 'setTimeout()'の結果を既に実行しているときに 'clearTimeout()'を使うロジックは意味がありません。タイマーは既に起動しています。 – jfriend00