2015-12-29 133 views
4

我在尝试使功能details()根据可用事件查找某些事件的细节(getdetails)。在下面的示例中,将询问具有ID ZRGZZ,RGHER和GRFDZ的事件的详细信息。这些细节应放置在一个数组中(信用额度为Theodore's answer)。结果应该是,当我打电话给details()时,结果数组被存储,所以我可以在以后使用它。我不知道如何返回这个最终数组。在数组构造完成之前执行console.log(JSON.stringify(res));。我知道这可能有事情做异步JS,但我不能换我的头周围...异步javascript问题

function details() 
{ 
    var res = { 
    "Result": "success", 
    "Key": "12345", 
    "Data": [{ 
     "ID": "ZRGZZ", 
     "lastChangedDate": "2015-12-03 11:14:27" 
    }, { 
     "ID": "RGHER", 
     "lastChangedDate": "2015-12-03 15:17:47" 
    }, { 
     "ID": "GRFDZ", 
     "lastChangedDate": "2015-12-03 05:25:11" 
    }] 
}; 

    var i = 0; 
    var tmp; 
    res.Data.map(function(val,i){ 

     getdetails(val.ID).then(function(data){ 
      tmp = JSON.parse(data); 
      console.log(tmp); 
      Object.keys(tmp.Data[0]).map(function(v,j){ 
       val[v] = tmp.Data[0][v]; 
       console.log(JSON.stringify(res)); //(*)the last res gives me the result I'm looking for 
      }); 

     }, function(error){ //error callback 
      console.log(error) 
     }); 


    }); 
console.log(JSON.stringify(res)); //this is executed before (*) 
} 
+0

试试这个:https://jsfiddle.net/rayon_1990/ks3vxomu/ – Rayon

+0

我在你的标签中看到了角度,如果你能够使用角度,使用$ http.get进行异步调用非常容易,它给你一个承诺(你需要的对象) – luk492

+0

@RayonDabre,似乎改变我的数据结构 – binoculars

回答

0

那么你已经在使用的承诺 - 看在你的代码then,如果它的角,然后then本身返回延期的承诺,所以你可以这样做:

res.Data.map(function (val, i) { 
    getdetails(val.ID).then(function (data) { 
     tmp = JSON.parse(data); 
     Object.keys(tmp.Data[0]).map(function (v, j) { 
      val[v] = tmp.Data[0][v]; 
     }); 
    }, function (error) { //error callback 
     console.log(error) 
    }).then(function() { 
     console.log(JSON.stringify(res)); 
    }) 
}); 

编辑:注射服务$q到您的控制器或服务

promises = []; 
res.Data.map(function (val) { 
    promises.push(getdetails(val.ID).then(function (data) { 
     tmp = JSON.parse(data); 
     Object.keys(tmp.Data[0]).map(function (v, j) { 
      val[v] = tmp.Data[0][v]; 
     }); 
    }, function (error) { //error callback 
     console.log(error) 
    })); 
}); 
$q.all(promises).then(function() { 
    console.log(JSON.stringify(res)); 
}); 

现在,当所有的getdetails都解决了,你可以CONSOLE.LOG或做任何你想要的数据

+0

感谢您的回复!这似乎工作!唯一不理想的是它'console.log(JSON.stringify(res));'被执行了x次(x是它要搜索的ID的数量)。 – binoculars

+1

我会用一点更复杂的解决方案来更新我的答案,以解决这个问题 – maurycy

+0

我试过你的更新答案,但现在'res'只保存第一个事件的细节。 – binoculars

1

一种方法是使用async库,特别是async.eachasync.eachSeries功能。 (你可以使用async.map,但在你的情况其实并不映射,而是直接修改底层数组项)

特别是,你的代码应该是这样的:

async.each(res.Data, function(val,callback){ 
    getdetails(val.ID).then(function(data){ 
     tmp = JSON.parse(data); 
     Object.keys(tmp.Data[0]).map(function(v,j){ 
      val[v] = tmp.Data[0][v]; 
     }); 
     callback(null); // Asynchronous code has finished without error 
    }, function(error){ //error callback 
     callback(error); // Asynchronous code has finished with error 
    }); 
}, function(error) { 
    // All asynchronous calls have finished 
    if(error) 
     console.log("Error", error); 
    else 
     console.log("Success", res); 
}); 

async.each将运行许多迭代同时进行,而async.eachSeries将只同时运行一次迭代。