gpt4 book ai didi

javascript - AWS S3/Javascript回调问题

转载 作者:行者123 更新时间:2023-12-01 01:21:19 26 4
gpt4 key购买 nike

因此,在对 AWS S3 进行 API 调用时,我遇到了 JavaScript 异步执行问题。

我有一系列嵌套回调,这些回调一直运行良好,直到我的代码不等待特定的 S3 调用。这是我的代码:

getThumbUrls(contentIndex, function(data) {
console.log('Returning from getThumbUrls');
// let's just display thumbUrls[0] for now...
console.log('The thumbUrls are ' + data[0]);
});

getThumbUrls() 看起来像这样:

function getThumbUrls(contentIndex, callback) {
console.log('Entering getThumbUrls');

var thumbUrls = [];

JSON.parse(contentIndex).forEach(videoKey => {
// get the thumbnail: bucket-name/thumbnails/<first-key>
console.log('videoKey = ' + videoKey);

getThumbFileName(videoKey, function(thumbFileName) {
console.log('Returning from getThumbFileName');
console.log('Returned thumb filename is ' + thumbFileName);

thumbUrls.push(CLOUDFRONT_URL + videoKey + '/thumbnails/' + thumbFileName);

});

});

callback(thumbUrls);
}

并且 getThumbFileName() 看起来像这样:

function getThumbFileName(videoKey, callback) {
console.log('Entering getThumbFileName...');

const s3 = new AWS.S3({
apiVersion: '2006-03-01',
params: {
Bucket: 'my-bucket-name'
}
});

// Get the name of the file.
params = {
Bucket: 'my-bucket-name',
Delimiter: '/',
Prefix: videoKey + '/' + THUMBS_FOLDER,
MaxKeys: 1
};

var urlKey;
//console.log('listObjects params = ' + JSON.stringify(params, null, 4));
s3.listObjectsV2(params, (err, data) => {
if (err) {
console.log(err, err.stack);
callback(err);
return;
}

var thumbsKey = data.Contents;
// MaxKeys was 1 bc first thumbnail key is good enough for now. Therefore, only one iteration.
thumbsKey.forEach(function (keys) {
console.log('thumbKey = ' + keys.Key);
urlKey = keys.Key;
});

});

callback(urlKey);
//callback('20161111-TheWind.jpg');
}

显然,发生的情况是执行不会等待 s3.listObjectsV2 调用完成。我已经验证,当所有 getThumbFileName() 所做的都是使用文件名进行回调时,整个流程可以正常工作。

有人可以告诉我如何强制执行等待s3.listObjectsV2完成,然后再以未定义的方式回调吗?

最佳答案

正如所讨论的,在处理迭代上的异步操作时,您应该避免使用回调方法,因为它们很困难。

<小时/>

(如果您不想了解 Promise 方法背后的动机,可以跳过本节)。

顺便提一下,在回调方法中,您必须等待 getThumbUrls() 中的所有回调完成,使用 if 来检查是否所有回调都已完成。回调已被调用,然后只需调用 callback(thumbUrls); 将所有响应推送到 thumbUrls 数组中:

function getThumbUrls(contentIndex, callback) {
const thumbUrls = [];

// counter which will increment by one for every callback
let counter = 0;
JSON.parse(contentIndex).forEach(videoKey => {
getThumbFileName(videoKey, function (thumbFileName) {
thumbUrls.push(CLOUDFRONT_URL + videoKey + '/thumbnails/' + thumbFileName);

// for each callback response you must add 1 to a counter and then
counter++;
// check if all callbacks already has been called
if (counter === JSON.parse(contentIndex).length) {
// right here, thumbsUrls are filled with all responses
callback(thumbUrls);
}
});
});
}
<小时/>

因此,您可以使用 Promise,并且 Promise.all 足以让您处理来自 api 的所有响应。您可以通过互联网学习并检查下面的代码,该代码使用了 promise 方法。我添加了一些评论来帮助您了解正在发生的事情。

// when using promises, no callbacks is needed
getThumbUrls(contentIndex)
.then(function (data) {
console.log('Returning from getThumbUrls');
// let's just display thumbUrls[0] for now...
console.log('The thumbUrls are ' + data[0]);

})

// when using promises, no callbacks is needed
function getThumbUrls(contentIndex) {
console.log('Entering getThumbUrls');

// not needed anymore, Promise.all will return all values
// var thumbUrls = [];

// Promise.all receives an array of promises and returns to next .then() all results
// changing forEach to map to return promises to my Promise.all
return Promise.all(JSON.parse(contentIndex).map(videoKey => {
console.log('videoKey = ' + videoKey);

// returning a promise
return getThumbFileName(videoKey)
.then(function (thumbFileName) {
console.log('Returning from getThumbFileName');
console.log('Returned thumb filename is ' + thumbFileName);

return CLOUDFRONT_URL + videoKey + '/thumbnails/' + thumbFileName;
});
}))
}

// when using promises, no callbacks is needed
function getThumbFileName(videoKey) {
console.log('Entering getThumbFileName...');

const s3 = new AWS.S3({
apiVersion: '2006-03-01',
params: {
Bucket: 'my-bucket-name'
}
});

// Get the name of the file.
params = {
Bucket: 'my-bucket-name',
Delimiter: '/',
Prefix: videoKey + '/' + THUMBS_FOLDER,
MaxKeys: 1
};

// urlKey not need anymore
// var urlKey;

// most of AWS functions has a .promise() method which returns a promise instead calling callback funcions
return s3.listObjectsV2(params).promise()
.then(function (data) {
var thumbsKey = data.Contents;
//if you want to return only first one thumbsKey:
return thumbsKey[0];
})
.catch(function (err) {
console.log(err, err.stack);
callback(err);
return;
})
}

希望这对你的学习有所帮助。

关于javascript - AWS S3/Javascript回调问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54209658/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com