如何在循环中递归承诺并将参数传递给另一个
How to recursive Promises in a loop and passing argument to another
我已经检查了 SO 上的其他线程,但 none 确实回答了问题,因为每个答案都省略了我的案例所需的内容,其中 none 是针对 Apple Music 的。 Apple API 是基于承诺的,甚至 async/await
returns 承诺而不是响应:(
我正在尝试获取我的所有播放列表,但 Apple 规定了 25 个偏移量限制,因此我必须分批执行此操作。
目前我以这样的方式结束:
async function getAllP() {
let totalresult =[];
window.music.api.music("/v1/me/library/playlists").then(function(o){
let re = o.data;
totalresult.push(re.data);
if ("next" in re) {
// what to insert here?
} else {
return totalresult;
}
});
}
在多次尝试在循环中正确创建 promise 或链接它们失败之后。我知道我需要一些递归函数。如果响应数据中存在关键字“next”,则此键的值为 url 以获取另一批播放列表,因此我需要将 url 传递给另一个 promise.But 我无法设置显式 .then 链接,因为我不知道该链有多长。在我的例子中,有 80 个播放列表,但其他用户可能有不同的数字,所以我正在努力解决的是如何编写 loop/recursive 内部函数,并传递适当的参数以在最后获得 totalresult
并且没有厄运金字塔
totalresult
是一个 'upper' 变量,用于存储所有响应对象。
更新:
对于那些想要响应数据的样子(从控制台复制)的人
getAllPlaylist()
Promise { <state>: "fulfilled", <value>: undefined }
music.api.music('/v1/me/library/playlists')
Promise { <state>: "pending" }
<state>: "fulfilled"
<value>: Object { request: {…}, response: Response, data: {…} }
data: Object { next: "/v1/me/library/playlists?offset=25", data: (25) […], meta: {…} }
data: Array(25) [ {…}, {…}, {…}, … ]
meta: Object { total: 80 }
next: "/v1/me/library/playlists?offset=25"
<prototype>: Object { … }
request: Object { baseUrl: "https://api.music.apple.com", path: "/v1/me/library/playlists", url: "https://api.music.apple.com/v1/me/library/playlists", … }
response: Response { type: "cors", url: "https://api.music.apple.com/v1/me/library/playlists", redirected: false, … }
<prototype>: Object { … }
<prototype>: Promise.prototype { … }
music.api.music('/v1/me/library/playlists?offset=25')
Promise { <state>: "pending" }
解决方案:
我不确定响应数据的样子。
我猜你看起来像下面这样:
注意:您可以自己处理错误。
async function getAllP() {
const totalresult = [];
let url = "/v1/me/library/playlists";
while (true) {
const o = await window.music.api.music(url);
const re = o.data;
totalresult.push(re.data);
if ("next" in re) {
url = re.next.url; // assume there is a url in the next.
continue;
}
break;
}
return totalresult;
}
希望这能解决您的问题,
const getAll = async () => {
const totalResult = [];
const getP = async (url) => {
const { data } = await window.music.api.music(url);
const hasMore = "next" in data;
totalResult.push(...data);
if (hasMore) return getP(data.next.url);
};
const url = "/v1/me/library/tracks";
await getP(url);
return totalResult;
};
You can do while(url)
and url = re.next.url
without ifs and continues and breaks.
@Thomas since when it's possible to write like that? isn't that confusing to read?
async function getAllP() {
const totalresult = [];
let url = "/v1/me/library/playlists";
while (url) {
const { data } = await window.music.api.music(url);
totalresult.push(...data.data);
url = data.next;
}
return totalresult;
}
@Sebastian,这读起来很混乱吗?
虽然我有一个 url,但是...
我已经检查了 SO 上的其他线程,但 none 确实回答了问题,因为每个答案都省略了我的案例所需的内容,其中 none 是针对 Apple Music 的。 Apple API 是基于承诺的,甚至 async/await
returns 承诺而不是响应:(
我正在尝试获取我的所有播放列表,但 Apple 规定了 25 个偏移量限制,因此我必须分批执行此操作。
目前我以这样的方式结束:
async function getAllP() {
let totalresult =[];
window.music.api.music("/v1/me/library/playlists").then(function(o){
let re = o.data;
totalresult.push(re.data);
if ("next" in re) {
// what to insert here?
} else {
return totalresult;
}
});
}
在多次尝试在循环中正确创建 promise 或链接它们失败之后。我知道我需要一些递归函数。如果响应数据中存在关键字“next”,则此键的值为 url 以获取另一批播放列表,因此我需要将 url 传递给另一个 promise.But 我无法设置显式 .then 链接,因为我不知道该链有多长。在我的例子中,有 80 个播放列表,但其他用户可能有不同的数字,所以我正在努力解决的是如何编写 loop/recursive 内部函数,并传递适当的参数以在最后获得 totalresult
并且没有厄运金字塔
totalresult
是一个 'upper' 变量,用于存储所有响应对象。
更新: 对于那些想要响应数据的样子(从控制台复制)的人
getAllPlaylist()
Promise { <state>: "fulfilled", <value>: undefined }
music.api.music('/v1/me/library/playlists')
Promise { <state>: "pending" }
<state>: "fulfilled"
<value>: Object { request: {…}, response: Response, data: {…} }
data: Object { next: "/v1/me/library/playlists?offset=25", data: (25) […], meta: {…} }
data: Array(25) [ {…}, {…}, {…}, … ]
meta: Object { total: 80 }
next: "/v1/me/library/playlists?offset=25"
<prototype>: Object { … }
request: Object { baseUrl: "https://api.music.apple.com", path: "/v1/me/library/playlists", url: "https://api.music.apple.com/v1/me/library/playlists", … }
response: Response { type: "cors", url: "https://api.music.apple.com/v1/me/library/playlists", redirected: false, … }
<prototype>: Object { … }
<prototype>: Promise.prototype { … }
music.api.music('/v1/me/library/playlists?offset=25')
Promise { <state>: "pending" }
解决方案:
我不确定响应数据的样子。 我猜你看起来像下面这样:
注意:您可以自己处理错误。
async function getAllP() {
const totalresult = [];
let url = "/v1/me/library/playlists";
while (true) {
const o = await window.music.api.music(url);
const re = o.data;
totalresult.push(re.data);
if ("next" in re) {
url = re.next.url; // assume there is a url in the next.
continue;
}
break;
}
return totalresult;
}
希望这能解决您的问题,
const getAll = async () => {
const totalResult = [];
const getP = async (url) => {
const { data } = await window.music.api.music(url);
const hasMore = "next" in data;
totalResult.push(...data);
if (hasMore) return getP(data.next.url);
};
const url = "/v1/me/library/tracks";
await getP(url);
return totalResult;
};
You can do
while(url)
andurl = re.next.url
without ifs and continues and breaks.
@Thomas since when it's possible to write like that? isn't that confusing to read?
async function getAllP() {
const totalresult = [];
let url = "/v1/me/library/playlists";
while (url) {
const { data } = await window.music.api.music(url);
totalresult.push(...data.data);
url = data.next;
}
return totalresult;
}
@Sebastian,这读起来很混乱吗?
虽然我有一个 url,但是...