2017-09-01 1155 views
0

我是一个较新的Node.js.I定义了一个数组作为局部变量,并且想在下面的中使用它,我在其中保存了一些有用的数据。但最后,阵列是空的。有人告诉我为什么?感谢您的支持。关于Node.js中的局部变量promise

const Device = require("./mongo.js").Device; 
const Video = require("./mongo.js").Video; 

Device.findOne({id:"11112222"}).exec() 
    .then(function(data){ 
    var videoIds = data.videoIds.split(","); 
    var videoId2URL = []; 
    console.log(videoIds); 
    videoIds.forEach(function(one){ 
      return Video.findOne({id:one}).exec() 
      .then(function(data){ 
       videoId2URL.push({id:one,url:data.url}); 
       return videoId2URL; 
      }) 

    }); 
    console.log(videoId2URL); 
}); 
+2

这里的主要问题是,你syncronous和asyncronous呼叫混合一起没有适当处理后。特别是当你使用'Promise'时,你正在使用异步代码,因此你需要改变代码流。基本上你在'forEach'迭代器中触发了多个Promise,但是在解析之前打印('console.log')。 – MarcoL

回答

0

的问题是,你是太早显示videoId2URL

Device.findOne返回一个异步执行的承诺。但Video.findOne也返回一个异步执行的承诺。

所以,当你做console.log(videoId2URL);,由Video.findOne创建的承诺尚未执行。所以你的数组是空的。

您必须等待所有承诺的结束。你可以使用Promise.all

Promise.all(videoIds.map(function(one){ 
     return Video.findOne({id:one}).exec() 

     .then(function(data){ 
      videoId2URL.push({id:one,url:data.url}); 
      return videoId2URL; 
     }); 
}) 

.then(function() { 
    console.log(videoId2URL); 
}); 
+0

为什么使用map而不是foreach,我测试了一下,使用map的时候代码可以运行但是使用foreach的时候失败了。谢谢。 –

+0

'forEach'什么都不返回。如果你想将一个数组映射到一个新的数组中,你必须使用'map' – Magus

0

您可以使用Promise.all来解决您的问题。您forEach代码包含异步代码。您的最后一行不会等待所有承诺解决。

尝试用:

var arr = []; 

videoIds.forEach(function(one){ 
      return arr.push(Video.findOne({id:one}).exec()); 
    }); 

Promise.all(arr) // here we are waiting for all async tasks to get resolved 
.then(function(data){ 
     console.log(data); 
     // parse your data here and find array of videoId2URL    
}) 
0

当你做console.log(videoId2URL),你仍然在为剧本的主栈,而没有push回调已被执行。

您可以使用数组来收集Video.findOne返回的承诺,最后使用Promise.all排除所有承诺,然后执行日志记录。

顺便说一句,2 return是没有必要的,你可以安全地删除它们。 第一个不使用,因为它在forEach的同步回调中​​。 第二个不使用,因为你依靠副作用,而不是使用已解决的值。

尝试:

const Device = require("./mongo.js").Device; 
 
const Video = require("./mongo.js").Video; 
 

 
Device.findOne({id:"11112222"}).exec() 
 
    .then(function(data){ 
 
    var videoIds = data.videoIds.split(","); 
 
    var videoId2URL = []; 
 
    var promiseArr = []; 
 
    console.log(videoIds); 
 
    videoIds.forEach(function(one){ 
 
     var p = Video.findOne({id:one}).exec() 
 
     .then(function(data){ 
 
     videoId2URL.push({id:one,url:data.url}); 
 
     }); 
 
     promiseArr.push(p); 
 
    }); 
 

 
    Promise.all(promiseArr).then(function() { 
 
     console.log(videoId2URL); 
 
    }); 
 
});