嗨,我想尝试做一些有点奇怪的事情,将异步和同步混合在一起,这就是为什么它没有按照我的预期工作。目前从阵列中为3个用户运行然后结束如何在数组中的整个用户名长度运行它?
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 :(得分: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);
答案 1 :(得分: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);
})
;
};
答案 2 :(得分:0)
我会添加另一个答案,因为接受的答案没有提供以下内容:
第一个解决方案使用Bluebird promise库,因为它显着简化了事情。特别是对于并发控制:
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
});
此第二个解决方案使用标准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");
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
});
或者,如果您同时发送所有请求的Twitter很好,您可以这样做:
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
});