Azure函数NodeJS:blobService.createAppendBlobFromLocalFile Promise无法解决

时间:2019-04-23 11:09:00

标签: node.js azure azure-functions azure-storage-blobs

我对天蓝色函数不熟悉,目前我只是想将图像作为Blob保存到我的存储中。但是,我的Promise从未解决,但是功能成功结束了。该图像存在于我的目录中。

到目前为止,这是我的代码:

module.exports = async function (context, req) {
    const path = require('path');
    const storage = require('azure-storage');
    const STORAGE_ACCOUNT_NAME = 'something';
    const ACCOUNT_ACCESS_KEY = 'also something';

    const blobService = storage.createBlobService(STORAGE_ACCOUNT_NAME, ACCOUNT_ACCESS_KEY);

    const filePath = './product-example.jpg';

    function uploadLocalFile (filePath) {
        return new Promise((resolve, reject) => {
            const fullPath = path.resolve(filePath);
            context.log('before call');
            blobService.createAppendBlobFromLocalFile('productimageupload', 'image-upload-post', fullPath, function(err) {
                if(err) {
                    context.log('err');
                    reject(err);
                } else {
                    context.log('resolve');
                    resolve({message: 'resolved successfully'});
                }
            });
        });
    };
    const output = uploadLocalFile(filePath);
    context.log(output);
};

这是执行函数时Protokoll的输出:

2019-04-23T11:03:46  Welcome, you are now connected to log-streaming service.
2019-04-23T11:03:59.185 [Information] Executing 'Functions.branding-tool-app' (Reason='This function was programmatically called via the host APIs.', Id=xyz)
2019-04-23T11:04:00.793 [Information] before call
2019-04-23T11:04:00.794 [Information] Promise { <pending> }
2019-04-23T11:04:00.926 [Information] Executed 'Functions.xyz' (Succeeded, Id=xzy)

如您所见,Promise的状态仍为“待处理”,并且在createBlob函数中无法解析。我在这里做什么错了?

1 个答案:

答案 0 :(得分:1)

这是将本地文件上传到blob的完整功能

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

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);
}

作为参考,我正在通过完整的快速入门功能。

const {
    Aborter,
    BlockBlobURL,
    ContainerURL,
    ServiceURL,
    SharedKeyCredential,
    StorageURL,
    uploadStreamToBlockBlob,
    uploadFileToBlockBlob
} = require('@azure/storage-blob');

const fs = require("fs");
const path = require("path");

if (process.env.NODE_ENV !== "production") {
    require("dotenv").config();
}

const STORAGE_ACCOUNT_NAME = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const ACCOUNT_ACCESS_KEY = process.env.AZURE_STORAGE_ACCOUNT_ACCESS_KEY;

const ONE_MEGABYTE = 1024 * 1024;
const FOUR_MEGABYTES = 4 * ONE_MEGABYTE;
const ONE_MINUTE = 60 * 1000;

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);
}

async function execute() {

    const containerName = "demo";
    const blobName = "quickstart.txt";
    const content = "hello!";
    const localFilePath = "./readme.md";

    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 blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, blobName);

    const aborter = Aborter.timeout(30 * ONE_MINUTE);

    console.log("Containers:");
    await showContainerNames(aborter, serviceURL);

    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);

    const downloadResponse = await blockBlobURL.download(aborter, 0);
    const downloadedContent = downloadResponse.readableStreamBody.read(content.length).toString();
    console.log(`Downloaded blob content: "${downloadedContent}"`);

    await blockBlobURL.delete(aborter)
    console.log(`Block blob "${blobName}" is deleted`);

    await containerURL.delete(aborter);
    console.log(`Container "${containerName}" is deleted`);
}

execute().then(() => console.log("Done")).catch((e) => console.log(e));

参考

https://github.com/Azure-Samples/azure-storage-js-v10-quickstart