搜索

首页  >  问答  >  正文

node.js - nodejs同步遍历接口10次该怎么写呢?

天蓬老师天蓬老师2786 天前449

全部回复(5)我来回复

  • 怪我咯

    怪我咯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/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 循环。

    回复
    0
  • 迷茫

    迷茫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);
        }
    })

    回复
    0
  • 黄舟

    黄舟2017-04-17 15:52:04

    Promise递归调用

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 15:52:04

    reduce就够用了。 具体自己想

    回复
    0
  • 迷茫

    迷茫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);
    });

    回复
    0
  • 取消回复