[英]Make asynchronous function with promises in JavaScript
I have a function 我有一个功能
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 '';
});
}
which downloades a remote image and uploads it to Amazon S3. 它将下载远程映像并将其上传到Amazon S3。 I want it to return the generated key.
我希望它返回生成的密钥。
I want to use the function like this 我想使用这样的功能
const images = ['http://...', 'http://...', ...].map((url, i) => {
return {
url: getImage(url, i)
}
});
Since my function getImage()
could take a little while for every single URL, I guess I will have to use asynchronous calls so that I'm sure that the function is completely done before moving on to the next element (or am I misunderstanding something?). 由于我的函数
getImage()
对于每个URL可能要花费一些时间,因此我想我将不得不使用异步调用,以便确保在移至下一个元素之前该函数已完全完成(否则我会误解某些内容) ?)。
I guess I have to use promises, so could a solution be something like this? 我想我必须使用诺言,所以解决方案可以是这样吗?
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);
});
});
}
and then use it like this: 然后像这样使用它:
const images = ['http://...', 'http://...', ...].map((url, i) => {
return {
url: getImage(url, i).then(url => url).catch(err => [])
}
});
As mentioned in the comments, axios is a promise. 如评论中所述,axios是一个承诺。 Should the code then look like
代码应该看起来像
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);
}
});
});
});
}
The use case is that I'm fetching a lot of blog posts from a public API. 用例是,我从公共API获取许多博客文章。 So I am doing something like
所以我正在做类似的事情
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);
})
};
});
So how would I structure the formatting of the array of blog posts? 那么我将如何构建博客文章数组的格式? The problem is that if an error happened, I don't want to include the image in the array of images.
问题是,如果发生错误,我不想在图像数组中包含该图像。 I am not sure how to check this with promises.
我不确定如何用承诺来检查这一点。
Using ECMAScript 2017 async
/ await
syntax, you can quite easily accomplish this. 使用ECMAScript 2017
async
/ await
语法,您可以轻松完成此操作。 Modifying the original form of your script, which you claim is working, it would look like the following: 修改您声称正在工作的脚本的原始形式,如下所示:
async function getImage(url, key) { try { const response = await axios({ method: 'get', url, responseType: 'stream' }) await s3.upload({ Key: key, Body: response.data, ContentType: response.data.headers['content-type'], ACL: 'public-read' }).promise() } catch (error) { // return error return key // since we don't have axios and s3 in here } return key } const blogPostsOriginal = [ { title: 'Title', images: ['url1', 'url2'] }, { title: 'Title', images: ['url1', 'url2'] }, { title: 'Title', images: ['url1', 'url2'] }, ]; Promise.all(blogPostsOriginal.map(async ({ title, images }) => { return { title, images: (await Promise.all(images.map(async (url) => { // get your key here somehow const key = Math.random().toString(36).slice(2, 12).padStart(10, 0) // upload image to S3 return getImage(url, key) }))) // after awaiting array of results, filter out errors .filter(result => !(result instanceof Error)) } })).then(blogPostsFormatted => { // use blogPostsFormatted here console.log(blogPostsFormatted) })
To explain the bit about s3.upload(...).promise()
, I got that from the documentation here and here . 为了解释有关
s3.upload(...).promise()
,我从此处和此处的文档中得到了这一点 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.