Руководство разработчика JavaScript для Функций AzureAzure Functions JavaScript developer guide

Это руководство содержит сведения о сложностях написания Функций Azure на языке JavaScript.This guide contains information about the intricacies of writing Azure Functions with JavaScript.

Функция JavaScript — это экспортированная функция , которая function выполняется при активации (триггеры настраиваются в файле function.json).A JavaScript function is an exported function that executes when triggered (triggers are configured in function.json). Первый аргумент, передаваемый каждой функции, является объектом context, который используется для получения и отправки данных привязки, ведения журнала и взаимодействия со средой выполнения.The first argument passed to every function is a context object, which is used for receiving and sending binding data, logging, and communicating with the runtime.

В этой статье предполагается, что вы уже прочли руководство для разработчиков по Функциям Azure.This article assumes that you have already read the Azure Functions developer reference. Выполните инструкции в кратком руководстве по функциям, чтобы создать свою первую функцию с помощью Visual Studio Code или на портале.Complete the Functions quickstart to create your first function, using Visual Studio Code or in the portal.

Эта статья также поддерживает разработку приложений TypeScript.This article also supports TypeScript app development.

Структура папокFolder structure

Необходимая структура папок для проекта JavaScript выглядит следующим образом.The required folder structure for a JavaScript project looks like the following. Это значение по умолчанию можно изменить.This default can be changed. Дополнительные сведения см. в разделе о scriptFile ниже.For more information, see the scriptFile section below.

FunctionsProject
 | - MyFirstFunction
 | | - index.js
 | | - function.json
 | - MySecondFunction
 | | - index.js
 | | - function.json
 | - SharedCode
 | | - myFirstHelperFunction.js
 | | - mySecondHelperFunction.js
 | - node_modules
 | - host.json
 | - package.json
 | - extensions.csproj

В корневой папке проекта существует общий файл host.json, который может использоваться для настройки приложения-функции.At the root of the project, there's a shared host.json file that can be used to configure the function app. У каждой функции есть папка с собственным файлом кода (JS) и файлом конфигурации привязки (function.json).Each function has a folder with its own code file (.js) and binding configuration file (function.json). Имя родительского каталога файла function.json всегда является именем этой функции.The name of function.json's parent directory is always the name of your function.

Расширения привязки, необходимые в версии 2.x среды выполнения функций, определены в файле extensions.csproj с фактическими файлами библиотеки в папке bin.The binding extensions required in version 2.x of the Functions runtime are defined in the extensions.csproj file, with the actual library files in the bin folder. При локальной разработке необходимо зарегистрировать расширения привязки.When developing locally, you must register binding extensions. При разработке функций на портале Azure эта регистрация выполняется автоматически.When developing functions in the Azure portal, this registration is done for you.

Экспорт функцииExporting a function

Функции JavaScript должны экспортироваться через module.exports (или exports).JavaScript functions must be exported via module.exports (or exports). Экспортированная функция должна быть функцией JavaScript, которая выполняется при активации.Your exported function should be a JavaScript function that executes when triggered.

По умолчанию среда выполнения Функций ищет функцию в файле index.js, где index.js использует тот же родительский каталог, что и соответствующий файл function.json.By default, the Functions runtime looks for your function in index.js, where index.js shares the same parent directory as its corresponding function.json. В стандартном случае экспортированная функция должна быть единственным экземпляром экспорта из соответствующего файла (экспорта с именем run или index).In the default case, your exported function should be the only export from its file or the export named run or index. Чтобы настроить расположение файла и имя экспорта функции, ознакомьтесь с разделом ниже о настройке точки входа функции.To configure the file location and export name of your function, read about configuring your function's entry point below.

Экспортированной функции передается число аргументов при выполнении.Your exported function is passed a number of arguments on execution. Первый аргумент, который она всегда принимает, — это объект context.The first argument it takes is always a context object. Если функция является синхронной (не возвращает обещание), необходимо передать context объект, так как для правильного использования требуется вызов context.done.If your function is synchronous (doesn't return a Promise), you must pass the context object, as calling context.done is required for correct use.

// You should include context, other arguments are optional
module.exports = function(context, myTrigger, myInput, myOtherInput) {
    // function logic goes here :)
    context.done();
};

Экспорт асинхронной функцииExporting an async function

При использовании объявленияasync function или простых обещаний JavaScript в версии 2.х среды выполнения Функций вам не нужно явно вызывать context.done, чтобы сообщить, что функция завершена.When using the async function declaration or plain JavaScript Promises in version 2.x of the Functions runtime, you do not need to explicitly call the context.done callback to signal that your function has completed. Ваша функция завершается при завершении экспортированной асинхронной функции или обещания.Your function completes when the exported async function/Promise completes. Для функций, предназначенных для среды выполнения версии 1.x, по-прежнему необходимо вызвать context.done после выполнения кода.For functions targeting the version 1.x runtime, you must still call context.done when your code is done executing.

Следующий пример — это простая функция, которая записывает в журнал, что она была запущена, и немедленно завершает выполнение.The following example is a simple function that logs that it was triggered and immediately completes execution.

module.exports = async function (context) {
    context.log('JavaScript trigger function processed a request.');
};

При экспорте асинхронной функции вы также можете настроить выходные привязки, чтобы принять значение return.When exporting an async function, you can also configure an output binding to take the return value. Мы рекомендуем выполнять этот шаг, если существует только одна выходная привязка.This is recommended if you only have one output binding.

Чтобы назначить выходные данные с помощью return, измените свойство name на $return в function.json.To assign an output using return, change the name property to $return in function.json.

{
  "type": "http",
  "direction": "out",
  "name": "$return"
}

В этом случае функция должна выглядеть следующим образом:In this case, your function should look like the following example:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    // You can call and await an async method here
    return {
        body: "Hello, world!"
    };
}

ПривязкиBindings

В JavaScript привязки настраиваются и определяются в файле function.json функции.In JavaScript, bindings are configured and defined in a function's function.json. Функции взаимодействуют с привязками несколькими способами.Functions interact with bindings a number of ways.

Входные данныеInputs

Входные данные в Функциях Azure делятся на две категории: входные данные от триггера и дополнительные входные данных.Input are divided into two categories in Azure Functions: one is the trigger input and the other is the additional input. Привязки триггера и другие привязки для ввода (привязки direction === "in") могут считываться функцией тремя способами.Trigger and other input bindings (bindings of direction === "in") can be read by a function in three ways:

  • [Рекомендуется.] Как параметры, передаваемые функции.[Recommended] As parameters passed to your function. Они передаются в функцию в том же порядке, в каком они определены в файле function.json.They are passed to the function in the same order that they are defined in function.json. Свойство name, определенное в Function. JSON , не обязано совпадать с именем параметра, хотя оно должно.The name property defined in function.json does not need to match the name of your parameter, although it should.

    module.exports = async function(context, myTrigger, myInput, myOtherInput) { ... };
    
  • Как элементы объекта context.bindings.As members of the context.bindings object. Каждый элемент назван по свойству name, определенному в файле function.json.Each member is named by the name property defined in function.json.

    module.exports = async function(context) { 
        context.log("This is myTrigger: " + context.bindings.myTrigger);
        context.log("This is myInput: " + context.bindings.myInput);
        context.log("This is myOtherInput: " + context.bindings.myOtherInput);
    };
    
  • В качестве входных данных при использовании объекта JavaScript arguments.As inputs using the JavaScript arguments object. Этот способ по сути идентичен передаче входных данных в качестве параметров, но позволяет динамически обрабатывать входные данные.This is essentially the same as passing inputs as parameters, but allows you to dynamically handle inputs.

    module.exports = async function(context) { 
        context.log("This is myTrigger: " + arguments[1]);
        context.log("This is myInput: " + arguments[2]);
        context.log("This is myOtherInput: " + arguments[3]);
    };
    

Выходные данныеOutputs

Выходные данные (привязки direction === "out") могут быть записаны в функцию несколькими способами.Outputs (bindings of direction === "out") can be written to by a function in a number of ways. Во всех случаях свойство name привязки, определенное в файле function.json, соответствует имени элемента объекта, записанного в функции.In all cases, the name property of the binding as defined in function.json corresponds to the name of the object member written to in your function.

Вы можете назначить данные выходным привязкам одним из следующих способов (не объединяя эти методы):You can assign data to output bindings in one of the following ways (don't combine these methods):

  • [Рекомендуется, если существует несколько экземпляров выходных данных.] Возврат объекта.[Recommended for multiple outputs] Returning an object. При использовании функции возврата Async/Promise можно вернуть объект с назначенными выходными данными.If you are using an async/Promise returning function, you can return an object with assigned output data. В приведенном ниже примере выходные привязки в файле function.json называются httpResponse и queueOutput.In the example below, the output bindings are named "httpResponse" and "queueOutput" in function.json.

    module.exports = async function(context) {
        let retMsg = 'Hello, world!';
        return {
            httpResponse: {
                body: retMsg
            },
            queueOutput: retMsg
        };
    };
    

    Если вы используете синхронную функцию, вы можете вернуть этот объект с помощью context.done (см. пример).If you are using a synchronous function, you can return this object using context.done (see example).

  • [Рекомендуется для одного экземпляра выходных данных.] Возвращает значение напрямую и с использованием имени привязки $return.[Recommended for single output] Returning a value directly and using the $return binding name. Этот метод работает для функций возврата (асинхронной или функции обещаний).This only works for async/Promise returning functions. См. пример в разделе Экспорт асинхронной функции.See example in exporting an async function.

  • Присвоение значений для свойства context.bindings . Вы можете присвоить значения непосредственно для context.bindings.Assigning values to context.bindings You can assign values directly to context.bindings.

    module.exports = async function(context) {
        let retMsg = 'Hello, world!';
        context.bindings.httpResponse = {
            body: retMsg
        };
        context.bindings.queueOutput = retMsg;
        return;
    };
    

Тип привязки данныхBindings data type

Чтобы определить тип данных для входной привязки, используйте свойство dataType в определении привязки.To define the data type for an input binding, use the dataType property in the binding definition. Например, чтобы прочитать содержимое HTTP-запроса в двоичном формате, используйте тип binary:For example, to read the content of an HTTP request in binary format, use the type binary:

{
    "type": "httpTrigger",
    "name": "req",
    "direction": "in",
    "dataType": "binary"
}

Параметры для dataType — это binary, stream и string.Options for dataType are: binary, stream, and string.

Объект contextcontext object

Среда выполнения использует объект context для передачи данных в функцию и из нее, а также для взаимодействия со средой выполнения.The runtime uses a context object to pass data to and from your function and to let you communicate with the runtime. Объект контекста может использоваться для чтения и настройки данных из привязок, записи журналов и применения обратного вызова context.done, если экспортированная функция является синхронной.The context object can be used for reading and setting data from bindings, writing logs, and using the context.done callback when your exported function is synchronous.

Объект context всегда является первым параметром функции.The context object is always the first parameter to a function. Он должен быть включен, так как содержит важные методы, такие как context.done и context.log.It should be included because it has important methods such as context.done and context.log. Для этого объекта можно указать любое имя (например, ctx или c).You can name the object whatever you would like (for example, ctx or c).

// You must include a context, but other arguments are optional
module.exports = function(ctx) {
    // function logic goes here :)
    ctx.done();
};

Свойство context.bindingscontext.bindings property

context.bindings

Возвращает именованный объект, используемый для чтения или назначения данных привязки.Returns a named object that is used to read or assign binding data. Доступ к данным входных и триггеров можно получить, читая свойства context.bindings.Input and trigger binding data can be accessed by reading properties on context.bindings. Данные выходной привязки могут быть назначены путем добавления данных в context.bindingsOutput binding data can be assigned by adding data to context.bindings

Например, следующие определения привязки в function.json позволяют вам получить доступ к содержимому очереди из context.bindings.myInput и назначить выходные данные очереди, используя context.bindings.myOutput.For example, the following binding definitions in your function.json let you access the contents of a queue from context.bindings.myInput and assign outputs to a queue using context.bindings.myOutput.

{
    "type":"queue",
    "direction":"in",
    "name":"myInput"
    ...
},
{
    "type":"queue",
    "direction":"out",
    "name":"myOutput"
    ...
}
// myInput contains the input data, which may have properties such as "name"
var author = context.bindings.myInput.name;
// Similarly, you can set your output data
context.bindings.myOutput = { 
        some_text: 'hello world', 
        a_number: 1 };

Вы можете определить выходные данные привязки с помощью метода context.done вместо объекта context.binding (см. ниже).You can choose to define output binding data using the context.done method instead of the context.binding object (see below).

Свойство context.bindingDatacontext.bindingData property

context.bindingData

Это свойство возвращает именованный объект, содержащий метаданные триггера и данные вызова функции (invocationId, sys.methodName, sys.utcNow, sys.randGuid).Returns a named object that contains trigger metadata and function invocation data (invocationId, sys.methodName, sys.utcNow, sys.randGuid). Пример метаданных триггера см. по этой ссылке с примером для концентраторов событий.For an example of trigger metadata, see this event hubs example.

Метод context.donecontext.done method

context.done([err],[propertyBag])

Позволяет среде выполнения узнать, что ваш код выполнен.Lets the runtime know that your code has completed. Если функция использует объявление async function, метод context.done() не требуется.When your function uses the async function declaration, you do not need to use context.done(). Обратный вызов context.done выполняется неявным образом.The context.done callback is implicitly called. Асинхронные функции доступны в Node 8 или более поздней версии, для которой требуется среда выполнения Функций версии 2.x.Async functions are available in Node 8 or a later version, which requires version 2.x of the Functions runtime.

Если функция не является асинхронной функцией, необходимо вызвать context.done, чтобы сообщить среде выполнения о завершении функции.If your function is not an async function, you must call context.done to inform the runtime that your function is complete. Если этот метод отсутствует, истекает время ожидания выполнения.The execution times out if it is missing.

Метод context.done позволяет передавать в среду выполнения и определяемые пользователем сообщения об ошибке, и объект JSON, содержащий выходные данные привязки.The context.done method allows you to pass back both a user-defined error to the runtime and a JSON object containing output binding data. Свойства, переданные в context.done, перезапишут любые значения, заданные для объекта context.bindings.Properties passed to context.done overwrite anything set on the context.bindings object.

// Even though we set myOutput to have:
//  -> text: 'hello world', number: 123
context.bindings.myOutput = { text: 'hello world', number: 123 };
// If we pass an object to the done function...
context.done(null, { myOutput: { text: 'hello there, world', noNumber: true }});
// the done method overwrites the myOutput binding to be: 
//  -> text: 'hello there, world', noNumber: true

Метод context.logcontext.log method

context.log(message)

Этот метод позволяет делать записи в потоковые журналы функций на уровне трассировки по умолчанию.Allows you to write to the streaming function logs at the default trace level. В context.log доступны дополнительные методы ведения журнала, позволяющие выполнять запись в журналы функций на других уровнях трассировки:On context.log, additional logging methods are available that let you write function logs at other trace levels:

МетодMethod DescriptionDescription
error(message)error(message) Записывает сообщение в журнал на уровне ошибок или более низком.Writes to error level logging, or lower.
warn(message)warn(message) Записывает сообщение в журнал на уровне предупреждений или более низком.Writes to warning level logging, or lower.
info(message)info(message) Записывает сообщение в журнал на уровне сведений или более низком.Writes to info level logging, or lower.
verbose(message)verbose(message) Записывает сообщение в журнал на уровне детализации.Writes to verbose level logging.

Следующий пример записывает в журнал на уровне трассировки "предупреждения":The following example writes a log at the warning trace level:

context.log.warn("Something has happened."); 

Вы можете настроить пороговое значение уровня трассировки для ведения журнала в файле host.json.You can configure the trace-level threshold for logging in the host.json file. Дополнительные сведения о записи журналов см. в разделе о записях выходных данных трассировки ниже.For more information on writing logs, see writing trace outputs below.

Дополнительные сведения о просмотре журналов функций и обращении к ним см. в статье мониторинг Функций Azure.Read monitoring Azure Functions to learn more about viewing and querying function logs.

Вывод выходных данных трассировки на консольWriting trace output to the console

В Azure Functions воспользуйтесь методами context.log для записи выходных данных трассировки в консоль.In Functions, you use the context.log methods to write trace output to the console. В Функциях версии 2.x трассировка выходных данных с помощью console.log регистрируется на уровне приложения-функции.In Functions v2.x, trace outputs using console.log are captured at the Function App level. Это означает, что выходные данные console.log не привязаны к конкретному вызову функции и не отображаются в журналах конкретной функции.This means that outputs from console.log are not tied to a specific function invocation and aren't displayed in a specific function's logs. Тем не менее они распространяются в Application Insights.They do, however, propagate to Application Insights. В Функциях версии 1.x для записи в консоль нельзя использовать метод console.log.In Functions v1.x, you cannot use console.log to write to the console.

При вызове context.log() ваше сообщение записывается в консоль на уровне трассировки по умолчанию — уровень сведений.When you call context.log(), your message is written to the console at the default trace level, which is the info trace level. Следующий код записывает на консоль на уровне трассировки "сведения":The following code writes to the console at the info trace level:

context.log({hello: 'world'});  

Этот код эквивалентен приведенному выше коду:This code is equivalent to the code above:

context.log.info({hello: 'world'});  

Этот код записывает в консоль на уровне трассировки "ошибки":This code writes to the console at the error level:

context.log.error("An error has occurred.");  

Так как уровень ошибок является наивысшим уровнем трасировки, эта трассировка записывается в выходные данные на всех уровнях трассировки при условии, что ведение журнала включено.Because error is the highest trace level, this trace is written to the output at all trace levels as long as logging is enabled.

Все методы context.log поддерживают тот же формат параметров, что и метод Node.js util.format.All context.log methods support the same parameter format that's supported by the Node.js util.format method. Просмотрите следующий код, который выполняет запись в журналы функций, используя уровень трассировки по умолчанию:Consider the following code, which writes function logs by using the default trace level:

context.log('Node.js HTTP trigger function processed a request. RequestUri=' + req.originalUrl);
context.log('Request Headers = ' + JSON.stringify(req.headers));

Этот же код можно записать в таком формате:You can also write the same code in the following format:

context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);
context.log('Request Headers = ', JSON.stringify(req.headers));

Настройка уровня трассировки для ведения журнала консолиConfigure the trace level for console logging

В Функциях Azure 1.x можно определить пороговое значение уровня трассировки для записи в консоль, чтобы легко контролировать, как трассировки записываются в консоль из ваших функций.Functions 1.x lets you define the threshold trace level for writing to the console, which makes it easy to control the way traces are written to the console from your function. Чтобы задать пороговое значение для всех трассировок, которые записываются в консоль, используйте свойство tracing.consoleLevel в файле host.json.To set the threshold for all traces written to the console, use the tracing.consoleLevel property in the host.json file. Этот параметр применяется ко всем функциям в приложении-функции.This setting applies to all functions in your function app. В следующем примере задается пороговое значение трассировки, чтобы включить подробное ведение журнала:The following example sets the trace threshold to enable verbose logging:

{
    "tracing": {
        "consoleLevel": "verbose"
    }
}  

Значения consoleLevel соответствуют именам методов в context.log.Values of consoleLevel correspond to the names of the context.log methods. Чтобы отключить ведение журнала трассировки в консоли, задайте для параметра consoleLevel значение off.To disable all trace logging to the console, set consoleLevel to off. Дополнительные сведения см. в справочной статье о host.json.For more information, see host.json reference.

Триггеры и привязки HTTPHTTP triggers and bindings

Триггеры HTTP и webhook, а также привязки вывода HTTP используют объекты запроса и ответа для обмена сообщениями HTTP.HTTP and webhook triggers and HTTP output bindings use request and response objects to represent the HTTP messaging.

Объект запросаRequest object

У объекта (запроса) context.req есть следующие свойства:The context.req (request) object has the following properties:

СвойствоProperty DescriptionDescription
bodybody Объект, содержащий текст запроса.An object that contains the body of the request.
headersheaders Объект, содержащий заголовок запроса.An object that contains the request headers.
methodmethod Метод HTTP, используемый для запроса.The HTTP method of the request.
originalUrloriginalUrl URL-адрес запроса.The URL of the request.
paramsparams Объект, содержащий параметры маршрутизации запроса.An object that contains the routing parameters of the request.
queryquery Объект, содержащий параметры запроса.An object that contains the query parameters.
rawBodyrawBody Текст сообщения в виде строки.The body of the message as a string.

Объект ответаResponse object

У объекта (ответа) context.res есть следующие свойства:The context.res (response) object has the following properties:

СвойствоProperty DescriptionDescription
bodybody Объект, содержащий текст ответа.An object that contains the body of the response.
headersheaders Объект, содержащий заголовок ответа.An object that contains the response headers.
isRawisRaw Указывает, что форматирование пропускается для ответа.Indicates that formatting is skipped for the response.
statusstatus Код состояния HTTP ответа.The HTTP status code of the response.

Доступ к запросу и ответуAccessing the request and response

При работе с триггерами HTTP вы можете получить доступ к объектам запроса и ответа HTTP одним из нескольких способов.When you work with HTTP triggers, you can access the HTTP request and response objects in a number of ways:

  • От свойств req и res объекта context.From req and res properties on the context object. В этом случае можно использовать обычный шаблон доступа к данным HTTP из объекта context вместо полного шаблона context.bindings.name.In this way, you can use the conventional pattern to access HTTP data from the context object, instead of having to use the full context.bindings.name pattern. Следующий пример демонстрирует доступ к объектам req и res в context:The following example shows how to access the req and res objects on the context:

    // You can access your HTTP request off the context ...
    if(context.req.body.emoji === ':pizza:') context.log('Yay!');
    // and also set your HTTP response
    context.res = { status: 202, body: 'You successfully ordered more coffee!' }; 
    
  • С помощью именованных входных и выходных привязок.From the named input and output bindings. В этом случае триггер и привязки HTTP работают как любая другая привязка.In this way, the HTTP trigger and bindings work the same as any other binding. В следующем примере объект ответа задается с помощью именованной привязки response:The following example sets the response object by using a named response binding:

    {
        "type": "http",
        "direction": "out",
        "name": "response"
    }
    
    context.bindings.response = { status: 201, body: "Insert succeeded." };
    
  • [Только ответ.] Путем вызова context.res.send(body?: any).[Response only] By calling context.res.send(body?: any). HTTP-ответ создается с входными данными body в качестве текста ответа.An HTTP response is created with input body as the response body. context.done() вызывается неявным образом.context.done() is implicitly called.

  • [Только ответ.] Путем вызова context.done().[Response only] By calling context.done(). Специальный тип привязки HTTP возвращает ответ, который передается методу context.done().A special type of HTTP binding returns the response that is passed to the context.done() method. Следующая привязка вывода HTTP определяет параметр вывода $return:The following HTTP output binding defines a $return output parameter:

    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
    
     // Define a valid response object.
    res = { status: 201, body: "Insert succeeded." };
    context.done(null, res);   
    

Масштабирование и параллелизмScaling and concurrency

По умолчанию функции Azure автоматически отслеживают нагрузку на приложение и при необходимости создают дополнительные экземпляры узлов для Node. js.By default, Azure Functions automatically monitors the load on your application and creates additional host instances for Node.js as needed. Функции используют встроенные пороговые значения (не настраиваемые пользователем) для различных типов триггеров, чтобы решить, когда следует добавлять экземпляры, например возраст сообщений и размер очереди для QueueTrigger.Functions uses built-in (not user configurable) thresholds for different trigger types to decide when to add instances, such as the age of messages and queue size for QueueTrigger. Дополнительные сведения см. в статье как работают планы потребления и Premium.For more information, see How the Consumption and Premium plans work.

Такое поведение масштабирования достаточно для многих приложений Node. js.This scaling behavior is sufficient for many Node.js applications. Для приложений, зависящих от ЦП, производительность можно повысить, используя несколько языковых рабочих процессов.For CPU-bound applications, you can improve performance further by using multiple language worker processes.

По умолчанию каждый экземпляр узла функций имеет один рабочий процесс с одним языком.By default, every Functions host instance has a single language worker process. Можно увеличить количество рабочих процессов на узел (до 10) с помощью параметра приложения FUNCTIONS_WORKER_PROCESS_COUNT .You can increase the number of worker processes per host (up to 10) by using the FUNCTIONS_WORKER_PROCESS_COUNT application setting. Затем функции Azure пытаются равномерно распределять одновременно вызовы функций между этими рабочими процессами.Azure Functions then tries to evenly distribute simultaneous function invocations across these workers.

FUNCTIONS_WORKER_PROCESS_COUNT применяется к каждому узлу, создаваемому функциями при масштабировании приложения для удовлетворения спроса.The FUNCTIONS_WORKER_PROCESS_COUNT applies to each host that Functions creates when scaling out your application to meet demand.

Версия узлаNode version

В следующей таблице показана версия Node.js, используемая каждой основной версией среды выполнения службы "Функции".The following table shows the Node.js version used by each major version of the Functions runtime:

Версия службы "Функции"Functions version Версия Node.jsNode.js version
1.x1.x 6.11.2 (заблокировано средой выполнения)6.11.2 (locked by the runtime)
2.x2.x Active LTS и обслуживание LTS версии Node. js (рекомендуется ~ 10).Active LTS and Maintenance LTS Node.js versions (~10 recommended). Нацеливание на версию в Azure, задав для параметра приложения WEBSITE_NODE_DEFAULT_VERSION значение ~10.Target the version in Azure by setting the WEBSITE_NODE_DEFAULT_VERSION app setting to ~10.

Введя process.version из любой функции или путем проверки параметра приложения, указанного выше, можно увидеть текущую версию, которую использует среда выполнения.You can see the current version that the runtime is using by checking the above app setting or by printing process.version from any function.

Управление зависимостямиDependency management

Чтобы использовать библиотеки сообщества в коде JavaScript, как показано в следующем примере, необходимо убедиться, что установлены все зависимости приложения-функции в Azure.In order to use community libraries in your JavaScript code, as is shown in the below example, you need to ensure that all dependencies are installed on your Function App in Azure.

// Import the underscore.js library
var _ = require('underscore');
var version = process.version; // version === 'v6.5.0'

module.exports = function(context) {
    // Using our imported underscore.js library
    var matched_names = _
        .where(context.bindings.myInput.names, {first: 'Carla'});

Примечание

Следует определить файл package.json в корне вашего приложения-функции.You should define a package.json file at the root of your Function App. После этого все функции в приложении будут совместно использовать одни и те же кэшированные пакеты, что обеспечивает наилучшую производительность.Defining the file lets all functions in the app share the same cached packages, which gives the best performance. При возникновении конфликтов версий их можно разрешить, добавив файл package.json в папку определенной функции.If a version conflict arises, you can resolve it by adding a package.json file in the folder of a specific function.

При развертывании приложения-функции из системы управления версиями любой файл package.json, присутствующий в вашем репозитории, вызовет npm install в своей папке во время развертывания.When deploying Function Apps from source control, any package.json file present in your repo, will trigger an npm install in its folder during deployment. Но при развертывании с помощью портала или интерфейса командной строки вам придется вручную устанавливать пакеты.But when deploying via the Portal or CLI, you will have to manually install the packages.

Существует два способа установки пакетов в приложение-функцию.There are two ways to install packages on your Function App:

Развертывание с зависимостямиDeploying with Dependencies

  1. Установите все необходимые пакеты в локальной среде, запустив npm install.Install all requisite packages locally by running npm install.

  2. Разверните свой код и убедитесь, что папка node_modules включена в развертывание.Deploy your code, and ensure that the node_modules folder is included in the deployment.

С помощью KuduUsing Kudu

  1. Перейдите к https://<function_app_name>.scm.azurewebsites.net.Go to https://<function_app_name>.scm.azurewebsites.net.

  2. Щелкните Debug Console (Консоль отладки) > CMD.Click Debug Console > CMD.

  3. Перейдите к D:\home\site\wwwroot, а затем перетащите файл package.json в папку wwwroot в верхней части страницы.Go to D:\home\site\wwwroot, and then drag your package.json file to the wwwroot folder at the top half of the page.
    Существуют другие способы передачи файлов в приложение-функцию.You can upload files to your function app in other ways also. Дополнительные сведения см. в разделе Как обновить файлы приложения-функции.For more information, see How to update function app files.

  4. После загрузки файла package.json запустите команду npm install в консоли удаленного выполнения Kudu.After the package.json file is uploaded, run the npm install command in the Kudu remote execution console.
    В результате этого действия будут загружены пакеты, указанные в файле package.json, и перезапущено приложение-функция.This action downloads the packages indicated in the package.json file and restarts the function app.

Переменные средыEnvironment variables

В Функциях параметры приложения, такие как строки подключения службы, доступны в виде переменных среды во время выполнения.In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. Вы можете получить доступ к этим параметрам с помощью process.env, как показано здесь во втором и третьем вызовах context.log(), где мы заносим в журнал переменные среды AzureWebJobsStorage и WEBSITE_SITE_NAME:You can access these settings using process.env, as shown here in the second and third calls to context.log() where we log the AzureWebJobsStorage and WEBSITE_SITE_NAME environment variables:

module.exports = async function (context, myTimer) {
    var timeStamp = new Date().toISOString();

    context.log('Node.js timer trigger function ran!', timeStamp);
    context.log("AzureWebJobsStorage: " + process.env["AzureWebJobsStorage"]);
    context.log("WEBSITE_SITE_NAME: " + process.env["WEBSITE_SITE_NAME"]);
};

Существует несколько способов для добавления, обновления и удаления параметров приложения-функции.There are several ways that you can add, update, and delete function app settings:

При локальном запуске приложения параметры считываются из файла проекта local.settings.json.When running locally, app settings are read from the local.settings.json project file.

Настройка точки входа функцииConfigure function entry point

Свойства function.json, а именно scriptFile и entryPoint, позволяют настроить расположение и имя экспортированной функции.The function.json properties scriptFile and entryPoint can be used to configure the location and name of your exported function. Эти свойства важны, если JavaScript является транскомпилированным.These properties can be important when your JavaScript is transpiled.

Использование scriptFileUsing scriptFile

По умолчанию функция JavaScript выполняется из файла index.js, который расположен в том же родительском каталоге, что и соответствующий файл function.json.By default, a JavaScript function is executed from index.js, a file that shares the same parent directory as its corresponding function.json.

scriptFile можно использовать для получения структуры папок, которая выглядит следующим образом:scriptFile can be used to get a folder structure that looks like the following example:

FunctionApp
 | - host.json
 | - myNodeFunction
 | | - function.json
 | - lib
 | | - sayHello.js
 | - node_modules
 | | - ... packages ...
 | - package.json

Файл function.json для myNodeFunction должен включать свойство scriptFile, указывающее на файл с экспортированной функцией, которую нужно выполнить.The function.json for myNodeFunction should include a scriptFile property pointing to the file with the exported function to run.

{
  "scriptFile": "../lib/sayHello.js",
  "bindings": [
    ...
  ]
}

Использование entryPointUsing entryPoint

В scriptFile (или index.js) функции должны экспортироваться с использованием module.exports, чтобы их можно было найти и запустить.In scriptFile (or index.js), a function must be exported using module.exports in order to be found and run. По умолчанию функция, которая выполняется при запуске, является единственным экземпляром экспорта (с именем run или index) из этого файла.By default, the function that executes when triggered is the only export from that file, the export named run, or the export named index.

Такой экспорт можно настроить, используя entryPoint в файле function.json, как показано в следующем примере:This can be configured using entryPoint in function.json, as in the following example:

{
  "entryPoint": "logFoo",
  "bindings": [
    ...
  ]
}

В среде Функций версии 2.x, которая поддерживает параметр this в пользовательских функциях, код этой самой функции может выглядеть следующим образом:In Functions v2.x, which supports the this parameter in user functions, the function code could then be as in the following example:

class MyObj {
    constructor() {
        this.foo = 1;
    };

    logFoo(context) { 
        context.log("Foo is " + this.foo); 
        context.done(); 
    }
}

const myObj = new MyObj();
module.exports = myObj;

В этом примере важно отметить, что хотя экспортируемый объект не гарантирует сохранения состояния между выполнениями.In this example, it is important to note that although an object is being exported, there are no guarantees for preserving state between executions.

Локальная отладкаLocal Debugging

При запуске с параметром --inspect процесс Node. js прослушивает клиент отладки на указанном порту.When started with the --inspect parameter, a Node.js process listens for a debugging client on the specified port. В функциях Azure 2. x можно указать аргументы для передачи в процесс Node. js, который выполняет код, добавив переменную среды или параметр приложения languageWorkers:node:arguments = <args>.In Azure Functions 2.x, you can specify arguments to pass into the Node.js process that runs your code by adding the environment variable or App Setting languageWorkers:node:arguments = <args>.

Чтобы выполнить отладку локально, добавьте "languageWorkers:node:arguments": "--inspect=5858" в разделе Values в файле Local. Settings. JSON и Подключите отладчик к порту 5858.To debug locally, add "languageWorkers:node:arguments": "--inspect=5858" under Values in your local.settings.json file and attach a debugger to port 5858.

При отладке с помощью VS Code параметр --inspect автоматически добавляется с использованием значения port в файле Launch. JSON проекта.When debugging using VS Code, the --inspect parameter is automatically added using the port value in the project's launch.json file.

В версии 1. x установка languageWorkers:node:arguments не будет работать.In version 1.x, setting languageWorkers:node:arguments will not work. Порт отладки можно выбрать с помощью параметра --nodeDebugPort в Azure functions Core Tools.The debug port can be selected with the --nodeDebugPort parameter on Azure Functions Core Tools.

TypeScriptTypeScript

Если вы используете версию 2. x среды выполнения функций, функции Azure для Visual Studio Code и Azure functions Core Tools позволяют создавать приложения-функции с помощью шаблона, поддерживающего проекты приложения-функции TypeScript.When you target version 2.x of the Functions runtime, both Azure Functions for Visual Studio Code and the Azure Functions Core Tools let you create function apps using a template that support TypeScript function app projects. Шаблон создает package.json и tsconfig.json файлы проекта, которые облегчают возможность пересчета, выполнения и публикации функций JavaScript из кода TypeScript с помощью этих средств.The template generates package.json and tsconfig.json project files that make it easier to transpile, run, and publish JavaScript functions from TypeScript code with these tools.

Созданный файл .funcignore используется для указания, какие файлы исключаются при публикации проекта в Azure.A generated .funcignore file is used to indicate which files are excluded when a project is published to Azure.

Файлы TypeScript (. TS) преобразуются в файлы JavaScript (JS) в dist выходном каталоге.TypeScript files (.ts) are transpiled into JavaScript files (.js) in the dist output directory. Шаблоны TypeScript используют параметрscriptFile в function.json, чтобы указать расположение соответствующего JS файла в папке dist.TypeScript templates use the scriptFile parameter in function.json to indicate the location of the corresponding .js file in the dist folder. Расположение выходных данных задается шаблоном с помощью параметра outDir в файле tsconfig.json.The output location is set by the template by using outDir parameter in the tsconfig.json file. Если изменить этот параметр или имя папки, среда выполнения не сможет найти код для выполнения.If you change this setting or the name of the folder, the runtime is not able to find the code to run.

Примечание

Экспериментальная поддержка TypeScript существует версии 1. x среды выполнения функций.Experimental support for TypeScript exists version 1.x of the Functions runtime. Экспериментальная версия преобразует файлы TypeScript в файлы JavaScript при вызове функции.The experimental version transpiles TypeScript files into JavaScript files when the function is invoked. В версии 2. x эта экспериментальная поддержка была заменена управляемым средством методом, который выполняет транспилирования до инициализации узла и во время процесса развертывания.In version 2.x, this experimental support has been superseded by the tool-driven method that does transpilation before the host is initialized and during the deployment process.

Способ, которым локально разрабатывается и развертывается в проекте TypeScript, зависит от вашего средства разработки.The way that you locally develop and deploy from a TypeScript project depends on your development tool.

Код Visual StudioVisual Studio Code

Функция Azure для расширения Visual Studio Code позволяет разрабатывать функции с помощью TypeScript.The Azure Functions for Visual Studio Code extension lets you develop your functions using TypeScript. Основные средства являются обязательным требованием к расширению функций Azure.The Core Tools is a requirement of the Azure Functions extension.

Чтобы создать приложение-функцию TypeScript в Visual Studio Code, выберите TypeScript в качестве языка при создании приложения-функции.To create a TypeScript function app in Visual Studio Code, choose TypeScript as your language when you create a function app.

При нажатии клавиши F5 для локального запуска приложения транспилирования выполняется перед инициализацией узла (Func. exe).When you press F5 to run the app locally, transpilation is done before the host (func.exe) is initialized.

При развертывании приложения-функции в Azure с помощью кнопки развернуть в приложении-функцию. расширение функций Azure сначала создает готовую к работе сборку файлов JavaScript из исходных файлов TypeScript.When you deploy your function app to Azure using the Deploy to function app... button, the Azure Functions extension first generates a production-ready build of JavaScript files from the TypeScript source files.

Azure Functions Core ToolsAzure Functions Core Tools

Существует несколько способов, которым проект TypeScript отличается от проекта JavaScript при использовании основных средств.There are several ways in which a TypeScript project differs from a JavaScript project when using the Core Tools.

Создание проектаCreate project

Чтобы создать проект приложения-функции TypeScript с помощью основных средств, необходимо указать параметр языка TypeScript при создании приложения-функции.To create a TypeScript function app project using Core Tools, you must specify the TypeScript language option when you create your function app. Это можно сделать одним из следующих способов:You can do this in one of the following ways:

  • Выполните команду func init, выберите node в качестве стека языка, а затем выберите typescript.Run the func init command, select node as your language stack, and then select typescript.

  • Выполните команду func init --worker-runtime typescript.Run the func init --worker-runtime typescript command.

Запустить локальноRun local

Чтобы запустить код приложения функции локально с помощью основных средств, используйте следующие команды вместо func host start.To run your function app code locally using Core Tools, use the following commands instead of func host start:

npm install
npm start

Команда npm start эквивалентна следующим командам:The npm start command is equivalent to the following commands:

  • npm run build
  • func extensions install
  • tsc
  • func start

Публикация в AzurePublish to Azure

Прежде чем использовать команду func azure functionapp publish для развертывания в Azure, создайте готовую к работе сборку файлов JavaScript из исходных файлов TypeScript.Before you use the func azure functionapp publish command to deploy to Azure, you create a production-ready build of JavaScript files from the TypeScript source files.

Следующие команды подготавливают и публикуют проект TypeScript с помощью основных средств:The following commands prepare and publish your TypeScript project using Core Tools:

npm run build:production 
func azure functionapp publish <APP_NAME>

В этой команде замените <APP_NAME> именем приложения функции.In this command, replace <APP_NAME> with the name of your function app.

Рекомендации для функций JavaScriptConsiderations for JavaScript functions

При работе с функциями JavaScript следует помнить о рекомендациях, приведенных в следующих разделах.When you work with JavaScript functions, be aware of the considerations in the following sections.

Выбор планов службы приложений для конфигурации с одним виртуальным ЦПChoose single-vCPU App Service plans

При создании приложения-функции, которое использует план службы приложения, мы советуем выбирать план для конфигурации с одним виртуальным ЦП вместо плана для нескольких виртуальных ЦП.When you create a function app that uses the App Service plan, we recommend that you select a single-vCPU plan rather than a plan with multiple vCPUs. Сейчас служба "Функции Azure" намного эффективнее выполняет функции JavaScript на виртуальных машинах с одним ЦП. Использование более крупных виртуальных машин не приводит к ожидаемому улучшению производительности.Today, Functions runs JavaScript functions more efficiently on single-vCPU VMs, and using larger VMs does not produce the expected performance improvements. При необходимости можно вручную развернуть, добавив несколько экземпляров одновиртуальных цпных виртуальных машин или включив Автомасштабирование.When necessary, you can manually scale out by adding more single-vCPU VM instances, or you can enable autoscale. Дополнительные сведения см. в статье Масштабирование числа экземпляров вручную или автоматически.For more information, see Scale instance count manually or automatically.

Холодный запускCold Start

С разработкой Функций Azure в виде бессерверной модели размещения холодные запуски стали реальностью.When developing Azure Functions in the serverless hosting model, cold starts are a reality. Холодный запуск обозначает, что когда ваше приложение-функция запускается в первый раз после периода отсутствия активности, запуск займет больше времени.Cold start refers to the fact that when your function app starts for the first time after a period of inactivity, it takes longer to start up. Для функций JavaScript, в частности с большими деревьями зависимостей, холодный запуск может оказаться достаточно длительным.For JavaScript functions with large dependency trees in particular, cold start can be significant. Чтобы ускорить процесс холодного запуска, по возможности выполняйте функции в виде файла пакета.To speed up the cold start process, run your functions as a package file when possible. Многие методы развертывания используют эту модель по умолчанию, но если возникают большие временные задержки при холодном запуске и он не выполняется из файла пакета, запуск в виде файла пакета может значительно ускорить процесс.Many deployment methods use the run from package model by default, but if you're experiencing large cold starts and are not running this way, this change can offer a significant improvement.

Пределы подключенияConnection Limits

При использовании зависящего от службы клиента в приложении "функции Azure" не создавайте новый клиент при каждом вызове функции.When you use a service-specific client in an Azure Functions application, don't create a new client with every function invocation. Вместо этого создайте в глобальной области один статический клиент.Instead, create a single, static client in the global scope. Дополнительные сведения см. в статье Управление подключениями в функциях Azure.For more information, see managing connections in Azure Functions.

Использование async и awaitUse async and await

При написании функций Azure в JavaScript следует писать код, используя ключевые слова async и await.When writing Azure Functions in JavaScript, you should write code using the async and await keywords. Написание кода с помощью async и await вместо обратных вызовов или .then и .catch с помощью обещания помогает избежать двух распространенных проблем:Writing code using async and await instead of callbacks or .then and .catch with Promises helps avoid two common problems:

  • Создание неперехваченных исключений, которые приводили к сбою процесса Node. js, потенциально влияя на выполнение других функций.Throwing uncaught exceptions that crash the Node.js process, potentially affecting the execution of other functions.
  • Непредвиденное поведение, например отсутствующие журналы из context. log, вызванные асинхронными вызовами, которые не ожидаются должным образом.Unexpected behavior, such as missing logs from context.log, caused by asynchronous calls that are not properly awaited.

В приведенном ниже примере асинхронный метод fs.readFile вызывается с функцией обратного вызова с ошибками в качестве второго параметра.In the example below, the asynchronous method fs.readFile is invoked with an error-first callback function as its second parameter. Этот код вызывает обе проблемы, упомянутые выше.This code causes both of the issues mentioned above. Исключение, которое не было явно перехвачено в правильной области, завершило работу со сбоем всего процесса (#1 проблемы).An exception that is not explicitly caught in the correct scope crashed the entire process (issue #1). Вызов context.done() вне области действия функции обратного вызова означает, что вызов функции может завершиться до того, как файл будет прочитан (вы#2).Calling context.done() outside of the scope of the callback function means that the function invocation may end before the file is read (issue #2). В этом примере вызов context.done() слишком ранних результатов в отсутствие записей журнала, начинающихся с Data from file:.In this example, calling context.done() too early results in missing log entries starting with Data from file:.

// NOT RECOMMENDED PATTERN
const fs = require('fs');

module.exports = function (context) {
    fs.readFile('./hello.txt', (err, data) => {
        if (err) {
            context.log.error('ERROR', err);
            // BUG #1: This will result in an uncaught exception that crashes the entire process
            throw err;
        }
        context.log(`Data from file: ${data}`);
        // context.done() should be called here
    });
    // BUG #2: Data is not guaranteed to be read before the Azure Function's invocation ends
    context.done();
}

Использование ключевых слов async и await помогает избежать обеих этих ошибок.Using the async and await keywords helps avoid both of these errors. Используйте функцию служебной программы Node. js, util.promisify , чтобы включить функции в стиле обратного вызова с ошибками в ожидающие функции.You should use the Node.js utility function util.promisify to turn error-first callback-style functions into awaitable functions.

В приведенном ниже примере все необработанные исключения, вызванные во время выполнения функции, не вызывают ошибку при отдельном вызове, вызвавшем исключение.In the example below, any unhandled exceptions thrown during the function execution only fail the individual invocation that raised an exception. Ключевое слово await означает, что шаги, следующие readFileAsync, выполняются только после завершения readFile.The await keyword means that steps following readFileAsync only execute after readFile is complete. При использовании async и awaitвам также не нужно вызывать обратный вызов context.done().With async and await, you also don't need to call the context.done() callback.

// Recommended pattern
const fs = require('fs');
const util = require('util');
const readFileAsync = util.promisify(fs.readFile);

module.exports = async function (context) {
    let data;
    try {
        data = await readFileAsync('./hello.txt');
    } catch (err) {
        context.log.error('ERROR', err);
        // This rethrown exception will be handled by the Functions Runtime and will only fail the individual invocation
        throw err;
    }
    context.log(`Data from file: ${data}`);
}

Дальнейшие действияNext steps

Для получения дополнительных сведений см. следующие ресурсы:For more information, see the following resources: