Javascript hell异步函数nodeJs的实践

Javascript hell异步函数nodeJs的实践,javascript,node.js,asynchronous,promise,request,Javascript,Node.js,Asynchronous,Promise,Request,我正在做一个学生项目。我的目标是收集并存储数据。 我在express中使用nodeJs,然后在Moviesdb上使用superagent运行查询以收集电影,然后将它们存储在neo4j上 以下是我的例子: app.get('/', function(req,res){ var hostname = "api.themoviedb.org/3"; var path = "/movie/"; // random id, to store random film for(i=0;i<3

我正在做一个学生项目。我的目标是收集并存储数据。 我在express中使用nodeJs,然后在Moviesdb上使用superagent运行查询以收集电影,然后将它们存储在neo4j上

以下是我的例子:

app.get('/', function(req,res){

var hostname = "api.themoviedb.org/3";
var path = "/movie/";



// random id, to store random film  
for(i=0;i<39;i++){
    randomId = Math.floor(Math.random() * 500) + 80;
    console.log(' --------------------- Random id is     ---------------------- ' + randomId);
    superagent.get(hostname + path + randomId)
        .query({ api_key: api_key, append_to_response : 'credits' })
        .end((err, res) => {
            if (err) { 
                if(err.status_code = '34') {
                    return console.log('id : ' + randomId + 'ne correspond pas à un film')
                }
                else{
                    return console.log(err);
                }
            }
            cpt ++;

            title = res.body.original_title;

            if(title){  // Test if title isn't nul, undefined, Nan, empty or 0 to add it
                console.log('randomId --> '  + res.body.id + '--> ' + title );
                if(!Filmadded.includes(film)){
                Filmadded.push(film);
            }       
            }               
        });

    }
                console.log('cpt : ' + cpt + '/39');
res.send('it works' + i );
});
app.get('/',函数(req,res){
var hostname=“api.themoviedb.org/3”;
var path=“/movie/”;
//随机id,用于存储随机胶片
对于(i=0;i{
如果(错误){
如果(err.status_code='34'){
return console.log('id:'+randomId+'ne correct pasáun film')
}
否则{
返回console.log(err);
}
}
cpt++;
标题=res.body.original_标题;
if(title){//测试title是否为nul、undefined、Nan、empty或0以添加它
console.log('randomId-->'+res.body.id+'-->'+title);
如果(!Filmadded.包括(胶片)){
添加胶片。推(胶片);
}       
}               
});
}
log('cpt:'+cpt+'/39');
res.send(“它工作”+i);
});
我只是在执行一个循环(39,因为api的限制是40) 对于每一部电影,我都要求拍一部电影

结果是:

如你所见,我首先显示了所有id,然后是与id匹配的标题。 -->我想等到请求结束后再继续。 我看起来像是答应过的,但我不是什么都有

我想我的身份证/胶卷问题就是因为这个


感谢您的帮助,并为我的英语感到抱歉

正如您所说,superagent的
get
函数是异步的,这意味着事件循环在执行下一个命令之前不会等待函数完成。因此,循环将启动40次循环执行,包括创建一个随机id,然后使用具有该id的superagent。因此,我们将讨论两个操作—一个是同步的,另一个是异步的

让我们从另一个角度来看。假设我们有以下循环:

for(i=0; i<39; i++) {
    const randomId = Math.floor(Math.random() * 500) + 80;
    console.log("RANDOM IS: ", randomId);
    setTimeout(function(){
        console.log("PRINT AGAIN: ", randomId);
    }, 10000);
}
for(i=0;i您的
superagent()
调用是异步的。因此,它不会阻塞,您的
for
循环只是运行到完成,并行启动所有39个
superagent()
调用。您可能可以编写代码并行运行所有这些调用(如果目标主机允许),但由于您要求能够一个接一个地运行它们,下面是一个函数的实现,它使用
superagent()
wait
的承诺功能来序列化
for
循环中的异步调用,以便它运行一个,等待它完成,然后运行下一个:

app.get('/', async function(req, res){

    let hostname = "api.themoviedb.org/3";
    let path = "/movie/";

    // random id, to store random film  
    for (let i = 0; i < 39; i++) {
        let randomId = Math.floor(Math.random() * 500) + 80;
        console.log(' --------------------- Random id is     ---------------------- ' + randomId);
        try {
            let result = await superagent.get(hostname + path + randomId)
                .query({ api_key: api_key, append_to_response : 'credits' });
            cpt ++;

            let title = result.body.original_title;

            if (title) {  // Test if title isn't nul, undefined, Nan, empty or 0 to add it
                console.log('randomId --> '  + res.body.id + '--> ' + title );
                if (!Filmadded.includes(film)) {
                    Filmadded.push(film);
                }       
            }               
        } catch(err) {
            if(err.status_code = '34') {
                console.log('id : ' + randomId + 'ne correspond pas à un film')
            }
            else{
                console.log(err);
            }   
        }
        console.log('cpt : ' + cpt + '/39');
    }
    res.send('it works' + i );
});
app.get('/',异步函数(req,res){
让hostname=“api.themoviedb.org/3”;
let path=“/movie/”;
//随机id,用于存储随机胶片
for(设i=0;i<39;i++){
让randomId=Math.floor(Math.random()*500)+80;
console.log('--------------Random id为--------------------Random id+Random id);
试一试{
让结果=等待superagent.get(主机名+路径+随机ID)
.query({api_键:api_键,将_附加到_响应:'credits');
cpt++;
让title=result.body.original_title;
if(title){//测试title是否为nul、undefined、Nan、empty或0以添加它
console.log('randomId-->'+res.body.id+'-->'+title);
如果(!Filmadded.包括(胶片)){
添加胶片。推(胶片);
}       
}               
}捕捉(错误){
如果(err.status_code='34'){
log('id:'+randomId+'ne correct pasáun film')
}
否则{
控制台日志(err);
}   
}
log('cpt:'+cpt+'/39');
}
res.send(“它工作”+i);
});
此外,您需要确保您正在声明您正在使用的所有变量,以便它们是意外全局变量,当有其他请求也在运行时可能会发生冲突

关于此代码,其他看起来不正确的事情,但我不知道您打算做什么:

  • 变量
    cpt
    看起来需要在某个地方初始化和声明
  • 变量
    Filmadded
    可能需要在本地确定作用域(而不是在服务器上运行多个请求时可能发生冲突的范围更大的变量)
  • superagent()
    调用失败时,不清楚您在这里实际打算如何处理错误。在这里,它只是记录错误,但如果您遇到错误,您可能需要能够返回错误状态

  • film和Filmadded的变量不知从何而来,cpt也是如此。你能发布完整的代码或指向git回购吗?