当下面的函数完成并提供数组’albums’中的项目的最终列表时,我希望它调用另一个函数/对列表执行其他操作.
目前它在函数完成之前发布[]并且我知道这是因为异步执行,但我认为Node是线性读取的,因为它是单线程的?
function getAlbumsTotal(list,params){ for(var i = 0; i<list.length; i++){ api.getArtistAlbums(list[i],params).then(function(data) { for(var alb = 0; alb<data.body.items.length; alb++){ albums.push(data.body.items[alb].id); } },function(err) { console.error(err); }); } console.log(albums); //do something with the finalized list of albums here }
解决方法
您提供给当时的回调函数确实是异步执行的,这意味着它只在当前调用堆栈中的其余代码执行完毕后执行,包括最终的console.log.
您可以这样做:
function getAlbumsTotal(list,params){ var promises = list.map(function (item) { // return array of promises // return the promise: return api.getArtistAlbums(item,params) .then(function(data) { for(var alb = 0; alb<data.body.items.length; alb++){ albums.push(data.body.items[alb].id); } },function(err) { console.error(err); }); }); Promise.all(promises).then(function () { console.log(albums); //do something with the finalized list of albums here }); }
注意:显然,专辑被定义为全局变量.这不是一个好设计.每个promise会提供自己的专辑子集会更好,并且Promise.all调用将用于将这些结果连接到局部变量中.这是这样的:
function getAlbumsTotal(list,params) .then(function(data) { // return the array of album IDs: return Array.from(data.body.items,function (alb) { return alb.id; }); },function(err) { console.error(err); }); }); Promise.all(promises).then(function (albums) { // albums is 2D array albums = [].concat.apply([],albums); // flatten the array console.log(albums); //do something with the finalized list of albums here }); }