nodejs如何让request变成同步执行

1、request

npm install request # 引入request包

代码示例:
var request = require(‘request’);
request(‘http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})

具体用法可以访问request


2、异步获取音乐外链

吾爱破解里面找到了一个网易云音乐的api

http://s.music.163.com/search/get/?type=1&s= 歌曲名/歌手名 &limit=5000

最开始打算得到一些歌曲的外链 代码如下:

var request = require('request');    
var url = require('url');    


var musicList = [];    
var musicNames = ['后会无期','那时雨','坏女孩','客官不可以'];    
var a = '';    


function parseJson(string){    
    try{ return JSON.parse(string) }    
    catch(e){ return null }    
}    

 function getMusicList(){    

    for(var i=0; i<musicNames.length; i++){   

        a = encodeURI(url.format({    
                    protocol: 'http',    
                    host: 's.music.163.com',    
                    pathname:'/search/get/',    
                    search: 'type=1&s=' + musicNames[i]   
                }));  

        request(a, /*{'proxy':'http://localhost:8080'},*/function (error, response, body) {  
                if(error) console.log('sss',error);  
                if (!error && response.statusCode == 200) {  
                    var json = parseJson(body);  
                    var song = json['result']['songs'][0]['audio'];  
                    musicList.push({  
                        musicName: musicNames[i],  
                        musicUrl: song  
                    });  
                    console.log(i,song);  
                }  
            });   
    }  

       
}     

getMusicList();   

运行结果如图:

4 ‘http://m2.music.126.net/cNNlA_VBZ9nlN0TIwXiCPw==/1000555581284331.mp3'
4 ‘http://m2.music.126.net/3U2HjYTHDZr31zmIi3rkog==/2062683813720120.mp3'
4 ‘http://m2.music.126.net/fVlwlAnEdhPvzVvdy277bw==/3340316325239022.mp3'
4 ‘http://m2.music.126.net/9YAcg9wQLLotcSDYDBarwA==/1396379775155535.mp3'

可以得知我们的确请求了4次request,但是最终请求的结果 i 的值都是4.当第一次执行console.log(i,song);的时候,i得值已经变成了4.这很好的体现了nodejs异步的特性。异步的优点就是并发,能够更快获取资源。再看一个例子:

var request = require('request');        
var url = require('url');       
var musicList = [];   
var musicNames = ['后会无期','那时雨','坏女孩','客官不可以'];   
var a = '';   


function parseJson(string){   
    try{ return JSON.parse(string) }
    catch(e){ return null }
}

 function getMusicList(i){


            a = encodeURI(url.format({
                protocol: 'http',
                host: 's.music.163.com',
                pathname:'/search/get/',
                search: 'type=1&s=' + musicNames[i]
            }));

            request(a, /*{'proxy':'http://localhost:8080'},*/function (error, response, body) {
                    if(error) console.log('sss',error);
                    if (!error && response.statusCode == 200) {
                        var json = parseJson(body);
                        var song = json['result']['songs'][0]['audio'];
                        musicList.push({
                            musicName: musicNames[i],
                            musicUrl: song
                        });
                        console.log(i,song);
                    }
                }); 
    }   
    
for(var i=0; i<musicNames.length; i++){
    getMusicList(i);
}    

运行结果如图:

通过这个例子就能体会到nodejs异步的特点了。


3、需求

如果我们就是想按照顺序获取歌曲呢?这就需要通过一些方法来处理了。


4、处理方式

方法一、

我们可以使用递归作为代码的执行控制工具。把需要执行的操作封装到一个函数中,在回调函数中通过递归调用控制代码的执行流程,废话不多说,上个代码吧:

var musicList = [];    
var musicNames = ['后会无期','那时雨','坏女孩','客官不可以'];    
var a = '';   
 (function getMusicList(i){  
            if(i >= musicNames.length) return true;  
            a = encodeURI(url.format({   
                protocol: 'http',  
                host: 's.music.163.com',  
                pathname:'/search/get/',  
                search: 'type=1&s=' + musicNames[i]  
            }));  
            request(a, /*{'proxy':'http://localhost:8080'},*/function (error, response, body) {  
                    if(error) console.log('sss',error);  
                    if (!error && response.statusCode == 200) {  
                        var json = parseJson(body);  
                        var song = json['result']['songs'][0]['audio'];  
                        musicList.push({  
                            musicName: musicNames[i],  
                            musicUrl: song  
                        });  
                        console.log(i,song);  
                        getMusicList(i + 1);  
                  }  
                });   
    })(0)  

运行结果如图:

以上代码已依次处理数组中的歌曲为例,介绍了通过递归的方式控制代码的执行流程。

应用到一些简单的场景中还是不错的,比如:我们将一个数组中的数据,依次保存到数据库中就可以采用这种方式。

通过递归的方式可以解决一些简单的异步回调问题。不过对于处理复杂的异步回调还是显得有些无能为力(如需要同步多个异步操作的结果)。

方法二、

强大的npm有很多很多模块,
直接调用同步的sync-request

(function getMusicList(){   

    for(var i=0; i<musicNames.length; i++){  
        a = encodeURI(url.format({  
        protocol: 'http',  
        host: 's.music.163.com',   
        pathname:'/search/get/',  
        search: 'type=1&s=' + musicNames[i]  
        }));  
        var json = parseJson(s_request('GET',a).getBody('utf8'));  
        var song = json['result']['songs'][0]['audio'];  
        musicList.push({  
            musicName: musicNames[i],  
            musicUrl: song  
        });  
        console.log(i,song);  
    }    
})();  

方法三、

request-promise

方法n

去 npmjs.org 搜索Async、Q、Promise等第三方库处理异步回调

方法n+1

拥抱ES6,替代回调函数,解决回调地狱问题
generator