【发布时间】:2018-01-02 06:00:57
【问题描述】:
我有一个函数
function getImage(url, key) {
return axios({
method: 'get',
url,
responseType: 'stream'
}).then(response => {
s3.upload({
Key: key,
Body: response.data,
ContentType: response.data.headers['content-type'],
ACL: 'public-read'
}, (err, data) => {
return key
});
}).catch(err => {
return '';
});
}
下载远程图像并将其上传到 Amazon S3。我希望它返回生成的密钥。
我想使用这样的功能
const images = ['http://...', 'http://...', ...].map((url, i) => {
return {
url: getImage(url, i)
}
});
由于我的函数 getImage() 对于每个 URL 都可能需要一些时间,我想我将不得不使用异步调用,以便我确定函数在移动到下一个元素之前完全完成(或者是我误会了什么?)。
我想我必须使用 Promise,所以解决方案可以是这样的吗?
function getImage(url, key) {
return new Promise((resolve, reject) => {
return axios({
method: 'get',
url,
responseType: 'stream'
}).then(response => {
s3.upload({
Key: key,
Body: response.data,
ContentType: response.data.headers['content-type'],
ACL: 'public-read'
}, (err, data) => {
resolve(key);
});
}).catch(err => {
reject(err);
});
});
}
然后像这样使用它:
const images = ['http://...', 'http://...', ...].map((url, i) => {
return {
url: getImage(url, i).then(url => url).catch(err => [])
}
});
编辑
正如 cmets 中提到的,axios 是一个承诺。那么代码应该看起来像
function getImage(url, key) {
return axios({
method: 'get',
url,
responseType: 'stream'
}).then(response => {
return new Promise((resolve, reject) => {
s3.upload({
Key: key,
Body: response.data,
ContentType: response.data.headers['content-type'],
ACL: 'public-read'
}, (err, data) => {
if (!err) {
resolve(key);
} else {
reject(err);
}
});
});
});
}
编辑 2
用例是我从公共 API 获取大量博客文章。所以我正在做类似的事情
const blogPostsOriginal = [
{ title: 'Title', images: ['url1', 'url2'] },
{ title: 'Title', images: ['url1', 'url2'] },
{ title: 'Title', images: ['url1', 'url2'] },
];
const blogPostsFormatted = blogPostsOriginal.map(blogPost => {
return {
title: blogPost.title,
images: blogPost.images.map(url => {
// upload image to S3
return getImage(url);
})
};
});
那么我将如何构建博客文章数组的格式?问题是如果发生错误,我不想将图像包含在图像数组中。我不知道如何用 Promise 来检查这个。
【问题讨论】:
-
当您调用
getImage时,它会通过axios创建一个promise。如果您想对不同的 URL 多次使用它,那么您会很好,因为每个 Promise 都会在它被解析时返回。在这种情况下,将axios包装在 Promise 对象中是多余的。 -
啊,我明白了。我已经更新了我的问题
标签: javascript node.js asynchronous promise axios