node.js - nodejs同步遍历接口10次该怎么写呢?
天蓬老师
天蓬老师 2017-04-17 15:50:04
0
5
454
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all(5)
刘奇

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/await

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

You can also encapsulate Promise yourself and then handle it through then - you can’t use for anyway...🎜

Parallel processing and reordering results

🎜I looked at it and I think you can fetch 10 pages of data asynchronously at the same time. After fetching, sort it according to a certain identifier (page number), and then process it in order🎜 rrreee

async/await

rrreee

Others

🎜Libraries such as Async, Q, Bluebird, and co all have ways to implement it, but they should not use for loops. 🎜
迷茫

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);
    }
})
黄舟

Promise recursive call

伊谢尔伦

reduce is enough. Think specifically

迷茫

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);
});
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template