angularjs $q.all 用于嵌套承诺
angularjs $q.all for nested promises
尝试在 AngularJS (1.6) 中获取嵌套的异步 REST 请求,然后在所有请求完成后执行代码。
我尝试使用 $q.all
,但似乎这不会考虑内部请求(剧集请求)。
如何修改以下示例,以便在所有请求完成后执行代码?
// foreach series --> load series details & seasons, foreach season --> load episodes
// when all requests are completed: do something
var requests = []
// e.g. series = [1]
series.forEach(function(seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function(data) {
console.log("received details for series "+seriesId)
// e.g. {id:1, title:"show 1"}
}))
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series "+seriesId+": ", data.seasons.length)
// e.g. [{id:11, title:"season 1"}, {id:12, title:"season 2"}]
data.seasons.map(function(e) {return e.id}).forEach(function(seasonId) {
requests.push(loadEpisodes(seasonId).then(function (data) {
console.log("received episodes for season "+seasonId+": ", data.episodes.length)
// e.g.
// season 11: [{id:111, title:"episode 1-1-1"}, {id:112, title:"episode 1-1-2"}, {id:113, title:"episode 1-1-3"}]
// season 12: [{id:121, title:"episode 1-2-1"}, {id:122, title:"episode 1-2-2"}]
}))
})
}))
})
$q.all(requests).then(function(result) {
console.log("*** all requests completed ***")
console.log(result.length)
})
上面的例子会 return 2 (1x loadSeriesDetails
, 1x loadSeasons
) 而不是 4 (1x loadSeriesDetails
, 1x loadSeasons
, 2x loadEpisodes
).
建议?提前致谢!
更新: 每个请求函数如下:
loadSeriesDetails = function(id) {
url = "..."+id
return $http.get(url).then(
function (result) {
return result.data
}, function (error) {
̶r̶e̶t̶u̶r̶n̶ ̶e̶r̶r̶o̶r̶
throw error;
});
}
您的 requests
数组应该包含您将其传递给 $q.all
时需要解决的所有承诺。目前,您正在将 loadEpisodes
的承诺添加到 requests
之前的承诺解决后。
您可以将其拆分,以便内部部分 return 属于自己的 $.q.all
,这将成为链接:
var requests = [];
series.forEach(function (seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function (data) {
console.log("received details for series " + seriesId);
return data;
}));
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series " + seriesId + ": ", data.seasons.length);
return loadAllEpisodes(data.seasons);
}));
});
function loadAllEpisodes(seasons) {
var requests = seasons.map(function (season) {
return loadEpisodes(season.id).then(function (data) {
console.log("received episodes for season " + season.id + ": ", data.episodes.length);
return data;
});
});
return $q.all(requests);
}
q.all(requests).then(function(result) {
console.log("*** all requests completed ***");
console.log(result.length);
});
请注意,在您的示例中,您仍然只会在从外部 $q.all
编辑 return 的最终数组中看到 2 个结果,因为您正在从最后一个承诺中获得结果每条链。因此,您可能需要调整 return 语句,以便它们按照您需要的方式对信息进行分组。
的变体,更接近原始代码片段。
// foreach series --> load series details & seasons, foreach season --> load episodes
// when all requests are completed: do something
var requests = []
// e.g. series = [1]
series.forEach(function(seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function(data) {
console.log("received details for series "+seriesId)
// e.g. {id:1, title:"show 1"}
}))
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series "+seriesId+": ", data.seasons.length)
// e.g. [{id:11, title:"season 1"}, {id:12, title:"season 2"}]
var innerRequests = [] // <<<==============
data.seasons.map(function(e) {return e.id}).forEach(function(seasonId) {
innerRequests.push(loadEpisodes(seasonId).then(function (data) {
console.log("received episodes for season "+seasonId+": ", data.episodes.length)
// e.g.
// season 11: [{id:111, title:"episode 1-1-1"}, {id:112, title:"episode 1-1-2"}, {id:113, title:"episode 1-1-3"}]
// season 12: [{id:121, title:"episode 1-2-1"}, {id:122, title:"episode 1-2-2"}]
}))
})
return $q.all(innerRequests) // <<<==============
}))
})
$q.all(requests).then(function(result) {
console.log("*** all requests completed ***")
console.log(result.length)
})
尝试在 AngularJS (1.6) 中获取嵌套的异步 REST 请求,然后在所有请求完成后执行代码。
我尝试使用 $q.all
,但似乎这不会考虑内部请求(剧集请求)。
如何修改以下示例,以便在所有请求完成后执行代码?
// foreach series --> load series details & seasons, foreach season --> load episodes
// when all requests are completed: do something
var requests = []
// e.g. series = [1]
series.forEach(function(seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function(data) {
console.log("received details for series "+seriesId)
// e.g. {id:1, title:"show 1"}
}))
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series "+seriesId+": ", data.seasons.length)
// e.g. [{id:11, title:"season 1"}, {id:12, title:"season 2"}]
data.seasons.map(function(e) {return e.id}).forEach(function(seasonId) {
requests.push(loadEpisodes(seasonId).then(function (data) {
console.log("received episodes for season "+seasonId+": ", data.episodes.length)
// e.g.
// season 11: [{id:111, title:"episode 1-1-1"}, {id:112, title:"episode 1-1-2"}, {id:113, title:"episode 1-1-3"}]
// season 12: [{id:121, title:"episode 1-2-1"}, {id:122, title:"episode 1-2-2"}]
}))
})
}))
})
$q.all(requests).then(function(result) {
console.log("*** all requests completed ***")
console.log(result.length)
})
上面的例子会 return 2 (1x loadSeriesDetails
, 1x loadSeasons
) 而不是 4 (1x loadSeriesDetails
, 1x loadSeasons
, 2x loadEpisodes
).
建议?提前致谢!
更新: 每个请求函数如下:
loadSeriesDetails = function(id) {
url = "..."+id
return $http.get(url).then(
function (result) {
return result.data
}, function (error) {
̶r̶e̶t̶u̶r̶n̶ ̶e̶r̶r̶o̶r̶
throw error;
});
}
您的 requests
数组应该包含您将其传递给 $q.all
时需要解决的所有承诺。目前,您正在将 loadEpisodes
的承诺添加到 requests
之前的承诺解决后。
您可以将其拆分,以便内部部分 return 属于自己的 $.q.all
,这将成为链接:
var requests = [];
series.forEach(function (seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function (data) {
console.log("received details for series " + seriesId);
return data;
}));
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series " + seriesId + ": ", data.seasons.length);
return loadAllEpisodes(data.seasons);
}));
});
function loadAllEpisodes(seasons) {
var requests = seasons.map(function (season) {
return loadEpisodes(season.id).then(function (data) {
console.log("received episodes for season " + season.id + ": ", data.episodes.length);
return data;
});
});
return $q.all(requests);
}
q.all(requests).then(function(result) {
console.log("*** all requests completed ***");
console.log(result.length);
});
请注意,在您的示例中,您仍然只会在从外部 $q.all
编辑 return 的最终数组中看到 2 个结果,因为您正在从最后一个承诺中获得结果每条链。因此,您可能需要调整 return 语句,以便它们按照您需要的方式对信息进行分组。
// foreach series --> load series details & seasons, foreach season --> load episodes
// when all requests are completed: do something
var requests = []
// e.g. series = [1]
series.forEach(function(seriesId) {
requests.push(loadSeriesDetails(seriesId).then(function(data) {
console.log("received details for series "+seriesId)
// e.g. {id:1, title:"show 1"}
}))
requests.push(loadSeasons(seriesId).then(function (data) {
console.log("received seasons for series "+seriesId+": ", data.seasons.length)
// e.g. [{id:11, title:"season 1"}, {id:12, title:"season 2"}]
var innerRequests = [] // <<<==============
data.seasons.map(function(e) {return e.id}).forEach(function(seasonId) {
innerRequests.push(loadEpisodes(seasonId).then(function (data) {
console.log("received episodes for season "+seasonId+": ", data.episodes.length)
// e.g.
// season 11: [{id:111, title:"episode 1-1-1"}, {id:112, title:"episode 1-1-2"}, {id:113, title:"episode 1-1-3"}]
// season 12: [{id:121, title:"episode 1-2-1"}, {id:122, title:"episode 1-2-2"}]
}))
})
return $q.all(innerRequests) // <<<==============
}))
})
$q.all(requests).then(function(result) {
console.log("*** all requests completed ***")
console.log(result.length)
})