怪我咯2017-04-17 15:52:04
如果你用 Node7,可以用 async/await 来写,刚好发了博客从地狱到天堂,还有以前写的 理解 async/await。
如果不用 Node7,Async 库的 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
循环。
迷茫2017-04-17 15:52:04
解决方法很多,这里可以采用q
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));
这样就会串行行请求urls数组里面的地址。
具体可以看这篇我写的文章nodejs q模块
或者可以采用ES6里面的generator和co模块来实现
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
使用Bluebird的Promise.mapSeries方法即可。
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);
});