Amazon S3 Node.js SDK deleteObjects

时间:2015-05-22 03:35:04

标签: javascript node.js amazon-s3

我试图在将几个对象复制到另一个文件夹后删除它们。 我的代码就像:

    var deleteParam = {
        Bucket: 'frontpass-test',
        Delete: {
            Objects: [
                {Key: '1.txt'},
                {Key: '2.txt'},
                {Key: '3.txt'}
            ]
        }
    };    
    s3.deleteObjects(deleteParam, function(err, data) {
        if (err) console.log(err, err.stack);
        else console.log('delete', data);
    });

,返回的数据是:

delete { Deleted: [ { Key: '1.txt' }, { Key: '3.txt' }, { Key: '2.txt' } ],
  Errors: [] }

所以我假设删除已经完成。但是对象仍然存在于文件夹中,我的代码有问题吗?

我还尝试使用for循环和s3.deleteObject删除对象,但它只删除了我的文件列表中的最后一个对象。

for (var i = 0; i < files.length; i++) {
    var copyParams = {
        Bucket: 'frontpass-test',
        CopySource: 'frontpass-test/unsold/' + files[i].filename,
        Key: 'sold/' + files[i].filename
    };      
    var deleteParam = {
        Bucket: 'frontpass-test',
        Key: 'unsold/' + files[i].filename
    };
    s3.copyObject(copyParams, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            s3.deleteObject(deleteParam, function(err, data) {
                if (err) console.log(err, err.stack);
                else console.log('delete', data);
            });
        }
    });
}

关于如何在我的案例中删除对象的任何想法?提前谢谢。

2 个答案:

答案 0 :(得分:1)

第一个例子看起来不错。您是否在存储桶中打开了对象版本控制?即使删除文件,也会保留文件的副本。

第二个例子实际上包含一些错误,可以解释为什么只删除最后一个错误。因为Node.js是异步的,所以当你点击copyObject函数调用时,循环迭代结束并进入下一次迭代,而不是等待copyObject上的回调被调用。您尝试使用params关键字为循环的每次迭代定义var变量,但由于Javascript具有功能级别范围而不是块级别范围,因此您实际上并未在每次迭代中创建新变量。您只有一个copyParmasdeleteParams的实例。因此,您可以快速浏览循环,deleteParams保持在循环的最后一次迭代中接收的值。然后最终copyObject来电的回调开始触发,他们都用deleteObject调用deleteParams,现在是 last 。为了在循环中进行多个异步调用,我喜欢使用async library。使用它,您可以执行以下操作:

async.each(files, function iterator(file, callback) {
    var copyParams = {
        Bucket: 'frontpass-test',
        CopySource: 'frontpass-test/unsold/' + file.filename,
        Key: 'sold/' + file.filename
    };      
    var deleteParam = {
        Bucket: 'frontpass-test',
        Key: 'unsold/' + file.filename
    };
    s3.copyObject(copyParams, function(err, data) {
        if (err) callback(err);
        else {
            s3.deleteObject(deleteParam, function(err, data) {
                if (err) callback(err)
                else {
                    console.log('delete', data);
                    callback();
                }
            });
        }
    });
}, function allDone(err) {
    //This gets called when all callbacks are called
    if (err) console.log(err, err.stack);
});

答案 1 :(得分:0)

只需要在s3之上实现文件夹重命名,我按如下方式执行:( promise api)

    _getDataForItemRename(from, to) {
    return s3.listObjectsV2({Bucket: services.conf.workspace, Prefix: from}).promise()
        .then((data) => {
            const toCopy = [];
            const toRemove = [];
            const s3Contents = Object.assign([], data.Contents);
            // in case of a single dir (with no children)
            if (s3Contents.length === 0) {
                s3Contents.push({Key: from});
            }
            s3Contents.forEach((item) => {
                const copyPromise = s3.copyObject({
                    Bucket: services.conf.workspace,
                    Key: to,
                    CopySource: services.conf.workspace + '/' + item.Key
                }).promise();

                const deletePromise = s3.deleteObjects({
                    Bucket: services.conf.workspace,
                    Delete: {Objects: [{Key: from}]}
                }).promise();

                toCopy.push(copyPromise);
                toRemove.push(deletePromise);
            });

            return {copy: toCopy, remove: toRemove};
        }).catch((err) => {
            return Promise.reject(err);
        });
}


            return this._getDataForItemRename(_from, _to).then((files) => {
            return Promise.all(files.copy).then(() => {
                return Promise.all(files.remove).then(result => {
                        return result;
                    });
            });
        }).catch((err) => {
            return Promise.reject(err);
        });