带有数组的多个嵌套 AJAX 请求
Multiple nested AJAX requests with arrays
我正在使用 Axios / promises 发出 AJAX 请求,但结构有点混乱。基本上我希望这种情况发生:
- 得到
masterlist.xml
.
- 解析主列表以获取类别列表 URL 数组。
- 得到每个
category.xml
.
- 解析每个类别列表以获取一组清单 URL。
- 获取每个
manifest.xml
并解析数据。
示例结构:
masterlist.xml
<master>
<category>action</category>
<category>romance</category>
</master>
类别 XML(例如 action.xml 和 romance.xml)
<manifestUrls>
<manifest>foo/bar/manifest.xml</manifest>
<manifest>alice/bob/manifest.xml</manifest>
<manifest>hello/world/manifest.xml</manifest>
</manifestUrls>
清单 XML
<manifest>
<data>Blah blah blah</data>
<manifest>
我对如何使用 then
将其构建为 Axios 请求有些困惑。我想要三个函数,getMaster()
、getCategory(url)
和 getManifest(url)
,它们最好是独立的(例如 getMaster
不必直接调用 getCategory
),但似乎有必要。
这在 Axios 中是如何构建的?
承诺的主要好处之一是它们可以让您轻松避免方法之间的相互依赖。
这里是您如何执行此操作的粗略概述。
// put it all together
getMaster()
.then(parseMaster)
.then(function (categories) {
return Promise.all(categories.map(getAndParseCategory));
})
.then(flatten) // the previous then() resolves to an array-of-arrays
.then(function (manifestUrls) {
return Promise.all(manifestUrls.map(getManifest));
})
.then(function (manifests) {
// manifests is an array of all manifests
});
// Examples of what each of the functions used above would do
function getMaster() {
return axios.get('masterUrl')
.then(function (response) { return response.data; });
}
function parseMaster(masterContent) {
// parse and return an array of categories
}
function getCategory(name) {
var url = // ... build the URL based on the name
return axios.get(url)
.then(function (response) { return response.data; });
}
function parseCategory(categoryContent) {
// parse and return an array of URLs synchronously for one category
}
function getAndParseCategory(name) {
return getCategory(name).then(parseCategory);
}
function getManifest(url) {
return axios.get(url)
.then(function (response) { return response.data; });
}
function flatten(arrayOfArrays) {
return [].concat.apply([], arrayOfArrays);
}
如果您使用的是 Bluebird 或其他提供 promises .map()
方法的东西,那么您可以稍微整理一下管道:
// using Promise.resolve() at the beginning to ensure
// the chain is based of the desired kind of promise
Promise.resolve()
.then(getMaster)
.then(parseMaster)
.map(getCategory)
.map(parseCategory)
.then(flatten) // previous line resolves to an array-of-arrays
.map(getManifest)
.then(function (manifests) {
// manifests is an array of all manifests
});
当然,如果您不想导入整个第三方 promise 库,您也可以定义自己的 .map
方法:
if (!Promise.prototype.map) {
Promise.prototype.map = function (func) {
return this.then(function (result) {
return Promise.all(result.map(func));
});
};
}
编辑: 在下面的评论中回答您的问题。如果您想传递类别文本,以便它可以包含在清单 URL 中,我认为一种干净的方法是将其包含在从 getCategory()
返回的数据中,以便 parseCategory
可以利用它。其他一切都可以保持不变。
示例:
function getCategory(name) {
var url = // ... build the URL based on the name
return axios.get(url)
.then(function (response) {
return {
name: name,
data: response.data
};
});
}
function parseCategory(categoryContent) {
var urls = // parse URLs from categoryContent.data
return urls.map(function (url) {
return categoryContent.name + '/' + url;
});
}
我正在使用 Axios / promises 发出 AJAX 请求,但结构有点混乱。基本上我希望这种情况发生:
- 得到
masterlist.xml
. - 解析主列表以获取类别列表 URL 数组。
- 得到每个
category.xml
. - 解析每个类别列表以获取一组清单 URL。
- 获取每个
manifest.xml
并解析数据。
示例结构:
masterlist.xml
<master>
<category>action</category>
<category>romance</category>
</master>
类别 XML(例如 action.xml 和 romance.xml)
<manifestUrls>
<manifest>foo/bar/manifest.xml</manifest>
<manifest>alice/bob/manifest.xml</manifest>
<manifest>hello/world/manifest.xml</manifest>
</manifestUrls>
清单 XML
<manifest>
<data>Blah blah blah</data>
<manifest>
我对如何使用 then
将其构建为 Axios 请求有些困惑。我想要三个函数,getMaster()
、getCategory(url)
和 getManifest(url)
,它们最好是独立的(例如 getMaster
不必直接调用 getCategory
),但似乎有必要。
这在 Axios 中是如何构建的?
承诺的主要好处之一是它们可以让您轻松避免方法之间的相互依赖。
这里是您如何执行此操作的粗略概述。
// put it all together
getMaster()
.then(parseMaster)
.then(function (categories) {
return Promise.all(categories.map(getAndParseCategory));
})
.then(flatten) // the previous then() resolves to an array-of-arrays
.then(function (manifestUrls) {
return Promise.all(manifestUrls.map(getManifest));
})
.then(function (manifests) {
// manifests is an array of all manifests
});
// Examples of what each of the functions used above would do
function getMaster() {
return axios.get('masterUrl')
.then(function (response) { return response.data; });
}
function parseMaster(masterContent) {
// parse and return an array of categories
}
function getCategory(name) {
var url = // ... build the URL based on the name
return axios.get(url)
.then(function (response) { return response.data; });
}
function parseCategory(categoryContent) {
// parse and return an array of URLs synchronously for one category
}
function getAndParseCategory(name) {
return getCategory(name).then(parseCategory);
}
function getManifest(url) {
return axios.get(url)
.then(function (response) { return response.data; });
}
function flatten(arrayOfArrays) {
return [].concat.apply([], arrayOfArrays);
}
如果您使用的是 Bluebird 或其他提供 promises .map()
方法的东西,那么您可以稍微整理一下管道:
// using Promise.resolve() at the beginning to ensure
// the chain is based of the desired kind of promise
Promise.resolve()
.then(getMaster)
.then(parseMaster)
.map(getCategory)
.map(parseCategory)
.then(flatten) // previous line resolves to an array-of-arrays
.map(getManifest)
.then(function (manifests) {
// manifests is an array of all manifests
});
当然,如果您不想导入整个第三方 promise 库,您也可以定义自己的 .map
方法:
if (!Promise.prototype.map) {
Promise.prototype.map = function (func) {
return this.then(function (result) {
return Promise.all(result.map(func));
});
};
}
编辑: 在下面的评论中回答您的问题。如果您想传递类别文本,以便它可以包含在清单 URL 中,我认为一种干净的方法是将其包含在从 getCategory()
返回的数据中,以便 parseCategory
可以利用它。其他一切都可以保持不变。
示例:
function getCategory(name) {
var url = // ... build the URL based on the name
return axios.get(url)
.then(function (response) {
return {
name: name,
data: response.data
};
});
}
function parseCategory(categoryContent) {
var urls = // parse URLs from categoryContent.data
return urls.map(function (url) {
return categoryContent.name + '/' + url;
});
}