Javascript 多重等待功能

Javascript 多重等待功能,javascript,node.js,async-await,Javascript,Node.js,Async Await,我有点难以接受JS的承诺 我正在使用一个库从Spotify中提取返回承诺的数据。 在我的主函数中,我可以使用wait从响应数据构建对象,并将其推送到数组(称为节点): var节点=[]; main(); 异步函数main(){ 变量id='0gusqTJKxtU1UTmNRMHZcv'; var artist=wait getArtistFromSpotify(id); 节点推送(艺术家); 当我在这里调试时,一切正常,节点有我的对象 但是,当我介绍第二个时,请等待下一个电话: nodes.f

我有点难以接受JS的承诺

我正在使用一个库从Spotify中提取返回承诺的数据。 在我的主函数中,我可以使用wait从响应数据构建对象,并将其推送到数组(称为节点):

var节点=[];
main();
异步函数main(){
变量id='0gusqTJKxtU1UTmNRMHZcv';
var artist=wait getArtistFromSpotify(id);
节点推送(艺术家);
当我在这里调试时,一切正常,节点有我的对象

但是,当我介绍第二个时,请等待下一个电话:

nodes.forEach((node,i)=>{
如果(node.done==false){
log(node.toString());
var-related_-artists=wait-getrelated-artists(node.spotify_-id);
我得到以下错误:SyntaxError:await仅在异步函数中有效

我以为第一个等待声明会得到解决,执行会一直持续到下一个

任何帮助都将不胜感激

编辑 其他功能(如果有帮助的话)如下所示:

函数getArtistFromSpotify(id){
让响应=spotify
.请求('https://api.spotify.com/v1/artists/'+id)。然后(函数(数据){
返回数据;
})
.catch(函数(err){
console.error('发生错误:'+err);
返回null;
});
返回响应;
}
函数getRelatedArtists(id){
让响应=spotify
.请求('https://api.spotify.com/v1/artists/“+id+”/相关艺术家”)。然后(函数(数据){
返回数据;
})
.catch(函数(err){
console.error('发生错误:'+err);
返回null;
});
返回响应;
}
函数buildArtistObject(数据){
变量艺术家={
node_id:nodes.length,
名称:空,
类型:空,
人气:空,
spotify_id:null,
完成:错误
}
artist.name=data.name;
artist.genres=data.genres;
artist.popularity=data.popularity>0?data.popularity:0;
artist.spotify_id=data.id;
回归艺术家;
}

下面的代码有多个问题

var nodes = [];    
main();
   
async function main() {
    var id = '0gusqTJKxtU1UTmNRMHZcv';
    var artist = await getArtistFromSpotify(id).then(data => buildArtistObject(data));
    nodes.push(artist);
// ...
首先,
main
变异全局范围
节点
。这不仅是一种反模式,即使在同步代码中也是如此(函数不应该依赖或修改全局变量名;而是使用参数和返回值),在异步代码中,
节点
除了在
main
中之外,在任何地方都无法使用。请参阅

其次,尽量避免将
然后
等待
组合在一起。这会让人困惑

还有一点奇怪的是,使用了一个
节点数组
,但只将一个
艺术家
推到它上面

关于该代码:

nodes.forEach((node, i) => {
    if (node.done == false) {
        console.log(node.toString());
        var related_artists =  await getRelatedArtists(node.spotify_id);

// ...
错误是不言自明的。如果希望封闭函数是异步的,则必须将
async
添加到封闭函数中:
nodes.forEach(async(node,i)=>{/…
。但这会为每个节点生成一个新的承诺链,这意味着依赖于结果的未来代码将无法等待循环解析中的所有承诺。请参阅。可能的解决方案是
for..of

虽然我不能100%确定您的最终目标是什么,但这是我将使用的一般模式:

async function main() {
  const id = '0gusqTJKxtU1UTmNRMHZcv';
  const data = await getArtistFromSpotify(id);
  const artist = await buildArtistObject(data);
  const nodes = [artist]; // odd but I assume you have more artists somewhere...
 
  for (const node of nodes) {
    if (!node.done) {
      const relatedArtists = await getRelatedArtists(node.spotify_id);
    }
  }
  /* or run all promises in parallel: 
  const allRelatedArtists = await Promise.all(
    nodes.filter(e => !e.done).map(e => getRelatedArtists(e.spotify_id))
  );
  */

  // ...
}

main();

因为你的代码不可运行,而且某些意图从上下文中不清楚,你可能需要对它进行一点修改,所以考虑它是伪代码。

< P>下面的代码有多个问题。

var nodes = [];    
main();
   
async function main() {
    var id = '0gusqTJKxtU1UTmNRMHZcv';
    var artist = await getArtistFromSpotify(id).then(data => buildArtistObject(data));
    nodes.push(artist);
// ...
首先,
main
变异全局范围
节点
。这不仅是一种反模式,即使在同步代码中也是如此(函数不应该依赖或修改全局变量名;而是使用参数和返回值),在异步代码中,
节点
除了在
main
中之外,在任何地方都无法使用。请参阅

其次,尽量避免将
然后
等待
组合在一起。这会让人困惑

还有一点奇怪的是,使用了一个
节点数组
,但只将一个
艺术家
推到它上面

关于该代码:

nodes.forEach((node, i) => {
    if (node.done == false) {
        console.log(node.toString());
        var related_artists =  await getRelatedArtists(node.spotify_id);

// ...
错误是不言自明的。如果希望封闭函数是异步的,则必须将
async
添加到封闭函数中:
nodes.forEach(async(node,i)=>{/…
。但这会为每个节点生成一个新的承诺链,这意味着依赖于结果的未来代码将无法等待循环解析中的所有承诺。请参阅。可能的解决方案是
for..of

虽然我不能100%确定您的最终目标是什么,但这是我将使用的一般模式:

async function main() {
  const id = '0gusqTJKxtU1UTmNRMHZcv';
  const data = await getArtistFromSpotify(id);
  const artist = await buildArtistObject(data);
  const nodes = [artist]; // odd but I assume you have more artists somewhere...
 
  for (const node of nodes) {
    if (!node.done) {
      const relatedArtists = await getRelatedArtists(node.spotify_id);
    }
  }
  /* or run all promises in parallel: 
  const allRelatedArtists = await Promise.all(
    nodes.filter(e => !e.done).map(e => getRelatedArtists(e.spotify_id))
  );
  */

  // ...
}

main();

因为你的代码不能运行,有些意图从上下文中不清楚,你可能需要适应这一点,所以考虑它是伪代码。

你对如何使用承诺有一些误解-

let response=spotify
.请求(url)
.then(函数(数据){return data})//这不做任何事情
.catch(函数(err){//不接受错误
console.error('发生错误:'+err);
返回null;
})
返回响应
你会很高兴有一种更简洁的方法来编写你的基本函数-

const getArtist=id=>
spotify
.请求('https://api.spotify.com/v1/artists/“+id)
const getRelatedArtists=id=>
spotify
.请求('https://api.spotify.com/v1/artists/“+id+”/相关艺术家“)
现在,在您的
main
函数中,我们可以
根据需要等待
。让我们首先看看如何使用单个艺术家ID-

异步函数main(artistId){ 常量artistData=等待getArtist(artistId) const relatedData=等待getRelatedArtists(artistId) 返回buildArtist(artistData,relatedData) } 如果你有很多艺术家ID-

异步函数main(artistIds){ 常量结果=[] for(ar的常数id)