Azure Blob如何在继续之前等待Blob创建?

时间:2019-02-06 17:00:22

标签: node.js azure async-await azure-blob-storage

我正在使用NodeJS和azure存储sdk,但存在一个问题,除非我添加一个中间函数来延迟它,以便将blob创建在文件之前,否则我上传到blob的文件将被创建为0kb文件。上传发生。从azure-storage sdk作为流或作为本地文件上传时,我得到相同的结果。

我具有以下功能:

async function uploadToBlob(localFilePath) {


        //ACTIVATE CREDENTIALS AND CONTAINER
    const credentials = new SharedKeyCredential(STORAGE_ACCOUNT_NAME, ACCOUNT_ACCESS_KEY);
    const pipeline = StorageURL.newPipeline(credentials);
    const serviceURL = new ServiceURL(`https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net`, pipeline);
    const containerURL = ContainerURL.fromServiceURL(serviceURL, containerName);  
    const aborter = Aborter.timeout(30 * ONE_MINUTE);

    //UPLOAD IMAGE
    var blobName = localFilePath.substring(localFilePath.lastIndexOf('/') + 1 );
    var fullBlobName = category + "/" + subcategory + "/" + blobName;
    var blobURL = await BlockBlobURL.fromContainerURL(containerURL, fullBlobName);

    await uploadImage(aborter, containerURL, localFilePath, blobURL)


}

通过在BlockBlobURL.fromContainerURL上等待来获取blobURL变量 如您所见,正在等待,并且对上载图片的调用也正在等待。

然后这是被调用的函数,该函数从azures sdk中调用uploadFileToBlockBlob:

//UPLOAD IMAGE NO-STREAM
async function uploadImage(aborter, containerURL, filePath, blobURL, blobName) {
    try {
        filePath = path.resolve(filePath);

         //THIS LINE MAKES IT WORK
        await showBlobNames(aborter, containerURL);

        addToDB(blobName, blobURL.url);


        console.log("Calling uploadFileToBlockBlob with filePath: " + filePath + 
                    " and blobURL: "+ blobURL.url)
        return await uploadFileToBlockBlob(aborter, filePath, blobURL);
    }
    catch(err) {
        console.log(err)
    }
}

在最后一个函数中,我添加了

await showBlobNames(aborter, containerURL);

这使它起作用。

似乎在创建blob之前就已上传文件,并且以正确的名称将图像上传到blob中但作为0kb文件,并且添加此功能会延迟它,以便可以创建Blob

我不明白为什么以前等待的对象直到创建Blob时才等待上传。我还尝试将上载调用放在回调函数中,但这样会在创建Blob时执行,但似乎不被支持(不调用回调函数)

我正在添加对showBlobNames的调用,但是我觉得我的代码不必依赖于此,我想了解为什么等待的arent起作用。

谢谢

1 个答案:

答案 0 :(得分:0)

这是我进行连接和执行CRUD操作的方式

    await containerURL.create(aborter);
    console.log(`Container: "${containerName}" is created`);

    await blockBlobURL.upload(aborter, content, content.length);
    console.log(`Blob "${blobName}" is uploaded`);
    
    await uploadLocalFile(aborter, containerURL, localFilePath);
    console.log(`Local file "${localFilePath}" is uploaded`);

    await uploadStream(aborter, containerURL, localFilePath);
    console.log(`Local file "${localFilePath}" is uploaded as a stream`);

    console.log(`Blobs in "${containerName}" container:`);
    await showBlobNames(aborter, containerURL);

这是相同的功能实现。

async function showContainerNames(aborter, serviceURL) {

    let response;
    let marker;

    do {
        response = await serviceURL.listContainersSegment(aborter, marker);
        marker = response.marker;
        for(let container of response.containerItems) {
            console.log(` - ${ container.name }`);
        }
    } while (marker);
}

async function uploadLocalFile(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath);
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    return await uploadFileToBlockBlob(aborter, filePath, blockBlobURL);
}

async function uploadStream(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath).replace('.md', '-stream.md');
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    const stream = fs.createReadStream(filePath, {
      highWaterMark: FOUR_MEGABYTES,
    });

    const uploadOptions = {
        bufferSize: FOUR_MEGABYTES,
        maxBuffers: 5,
    };

    return await uploadStreamToBlockBlob(
                    aborter, 
                    stream, 
                    blockBlobURL, 
                    uploadOptions.bufferSize, 
                    uploadOptions.maxBuffers);
}

async function showBlobNames(aborter, containerURL) {

    let response;
    let marker;

    do {
        response = await containerURL.listBlobFlatSegment(aborter);
        marker = response.marker;
        for(let blob of response.segment.blobItems) {
            console.log(` - ${ blob.name }`);
        }
    } while (marker);
}

在我的示例中,我已将javascript SDK 10用于azure存储,并且对我来说效果很好。有关源回购,请参阅https://github.com/Azure-Samples/azure-storage-js-v10-quickstart

希望有帮助。

MV