怪我咯2017-04-17 15:52:04
If you use Node7, you can use async/await to write. I just posted the blog From Hell to Heaven, and I also wrote about understanding async/await before.
If Node7 is not used, Async library's waterfall()
should be able to handle your problem. For details, please refer to the first blog above. waterfall()
应该可以处理你的问题,具体参考上述第一篇博客。
也可以自己封装 Promise,然后通过 then 来处理——反正也是不能用 for 的……
我看了下,我觉得你这个需要可以同时异步去取 10 页的数据,取完之后按一定的标识(页码)进行排序,再按顺序来加工
const requests = Array.apply(null, { length: 10 })
.map((n, index) => index)
.map(page => new Promise((resolve, reject) => {
request(`${queryStringSql}&page=${page}`, function(error, response, body) {
if (error || response.statusCode != 200) {
reject(error);
} else {
resolve({
page: page,
body: body
});
}
});
}));
Promise.all(requests)
.then(function(results) {
const sorted = results
.sort((r1, r2) => r1.page - r2.page)
.map(r => r.body);
sorted.forEach(body => {
// 这里已经按页码排好序了,该干啥干啥
});
});
async function doIt() {
for (var i = 0; i < 10; i++) {
const body = await new Promise((resolve, reject) => {
request(`${queryStringSql}&page=${i}`, function(error, response, body) {
if (error || response.statusCode != 200) {
reject(error);
} else {
resolve(body);
}
});
});
console.log(body);
}
}
doIt();
Async、Q、Bluebird、co 这些库都有办法实现,但应该都不是用 for
for
loops. 🎜迷茫2017-04-17 15:52:04
There are many solutions, you can adopt them hereq
var Q = require('q');
var request = require('request');
var urls = [
'http://localhost:3014/q-test/address1',
'http//localhost:3014/q-test/address2', // this is wrong address
'http://localhost:3014/q-test/address3',
'done' // append a useless item
];
function createPromise(url){
var deferred = Q.defer();
request(url , function(err , response , body){
if(err)
deferred.reject(err);
else
deferred.resolve(body);
});
return deferred.promise;
}
urls.reduce(function(soFar , url){
return soFar.then(function(data){
if(data)
console.log(data);
return createPromise(url); // 返回下一个请求的promise
} ,function(err){
console.error(err);
return createPromise(url);// 返回下一个请求的promise
})
},Q(null));
This will serially request the addresses in the urls array.
For details, you can read this article I wrote about nodejs q module
Or you can use the generator and co modules in ES6 to achieve it
const rp = require('request-promise');
const co = require('co');
let urls = [
// url1
// url2
// url3
];
co(function*(){
for(let i=0; i<urls.length; ++i){
var response = yield rp(urls[i]);
console.log(response);
}
})
迷茫2017-04-17 15:52:04
Just use Bluebird’s Promise.mapSeries method.
var Promise = require("Bluebird");
var request = require("request");
var _ = require("underscore");
// 将request模块Promise化
Promise.promisifyAll("request");
// 生成[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var N = _.range(10);
// 依次顺序遍历N数组
Promise.mapSeries(N, function(i)
{
return requestAsync(queryStringSql + '&page=' + i + '')
.then(function(response, body)
{
if (response.statusCode == 200)
{
cardsList.concat(JSON.parse(body)['cards']);
}
});
})
.catch(function(error) {
console.log(error);
});