Подтвердить что ты не робот

Понимание асинхронного кода в терминах Layman

Я понимаю основную суть асинхронности: вещи не выполняются последовательно. И я понимаю, что в этом есть что-то очень мощное... якобы. Но для жизни я не могу окутать голову в код. Давайте взглянем на async Node.JS-код, который я ПИСЬЕТ... но не понимаю.

function newuser(response, postData) {
    console.log("Request handler 'newuser' was called.");
    var body = '<html>' + 
        '<head>' +
        '<meta http-equiv="Content-Type" content="text/html; ' +
        'charset=UTF-8" />' +
        '</head>' +
        '<body>' +
        '<form action=" /thanks" method="post">' +
        '<h1> First Name </h1>' +
        '<textarea name="text" rows="1" cols="20"></textarea>' +
        '<h1> Last Name </h1>' +
        '<textarea name="text" rows="1" cols="20"></textarea>' +
        '<h1> Email </h1>' +
        '<textarea name="text" rows="1" cols="20"></textarea>' +
        '<input type="submit" value="Submit text" />' +
        '</body>' +
        '</html>';
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(body);
    response.end();
}

Откуда появился ответ? PostData? Почему я не могу определить переменную в этом "обратном вызове", а затем использовать ее за пределами обратного вызова? Есть ли способ, чтобы несколько вещей были последовательными, а затем остальная часть программы async?

4b9b3361

Ответ 1

Я не уверен, что эта функция используется, но точка обратных вызовов заключается в том, что вы передаете их в некоторую функцию, которая выполняется асинхронно; он сохраняет ваш обратный вызов, и когда эта функция выполняется с тем, что ему нужно сделать, она вызовет ваш обратный вызов с необходимыми параметрами. Примером может быть, например, пример спереди-назад.

Представьте, что у нас есть фреймворк, и в нем есть операция, которая выполняется в течение длительного времени, извлекая некоторые данные из базы данных.

function getStuffFromDatabase() {
  // this takes a long time
};

Так как мы не хотим, чтобы он выполнялся синхронно, мы разрешаем пользователю передавать обратный вызов.

function getStuffFromDatabase(callback) {
  // this takes a long time
};

Мы будем симулировать длительное время с вызова setTimeout; мы также притворимся, что у нас есть некоторые данные из базы данных, но мы просто скопируем строковое значение.

function getStuffFromDatabase(callback) {
  setTimeout(function() {
    var results = "database data";
  }, 5000);
};

Наконец, как только мы получим данные, мы будем называть обратный вызов, предоставленный нам пользователем функции фреймворка.

function getStuffFromDatabase(callback) {
  setTimeout(function() {
    var results = "database data";
    callback(results);
  }, 5000);
};

Как пользователь рамки, вы бы сделали что-то вроде этого, чтобы использовать функцию:

getStuffFromDatabase(function(data) {
  console.log("The database data is " + data);
});

Итак, как вы можете видеть, data (то же, что и response и postData в вашем примере) поступает из функции, через которую вы передаете свой обратный вызов; он дает эти данные вам, когда он знает, какие данные должны быть.

Причина, по которой вы не можете установить значение в своем обратном вызове и использовать его вне обратного вызова, заключается в том, что сам обратный вызов происходит не позже времени.

//  executed immediately  executed sometime in the future
//      |                  |       by getStuffFromDatabase
//      v                  v
getStuffFromDatabase(function(data) {
  var results = data; // <- this isn't available until sometime in the future!
});

console.log(results); // <- executed immediately

При запуске console.log присвоение var results еще не выполнено!

Ответ 2

У вас есть несколько несвязанных вопросов:

1) Сила async может выполнять несколько операций одновременно без блокировки основного потока. В node и js в общем случае это относится, в частности, к запросам файла ajax. Это означает, что я могу отключить несколько асинхронных вызовов для восстановления файлов, а не блокировать основной поток, пока он отображает контент. Моя предпочтительная структура - это jQuery, которая имеет удобный $.Deferred, который обертывает и стандартизирует асинхронные вызовы для использования jQuery.

2) response и postData поступают из родительского метода. Здесь нет ничего волшебного, это обычный вызов функции, поэтому значения этих данных создаются в другом месте и передаются в этот вызов. В зависимости от структуры node у вас есть точная подпись вашего метода.

3) Вы можете определить глобальную переменную в своем обратном вызове, если она правильно определена. Кажется, что вам нужна помощь в изучении того, что такое область действия. Вот несколько ссылок

http://www.digital-web.com/articles/scope_in_javascript/

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

4) Как только вы перейдете на асинхронный режим, вы никогда не сможете вернуться назад, используя обещания и отложенные объекты, такие как jQuery Deferreds, вы можете дождаться завершения нескольких асинхронных операций, прежде чем продолжить выполнение в еще одном асинхронном режиме. Отсрочка - ваши друзья.

http://api.jquery.com/category/deferred-object/

Ответ 3

Похоже, вы работаете через Node Книга для начинающих. Я призываю вас работать через всю книгу, это действительно отличное введение. Если вы пытаетесь лучше понять Javascript, видео Douglas Crockford на YouTube - отличный обзор: 1, 2.

Кусок кода, который вы опубликовали, не имеет достаточного контекста для меня, чтобы действительно помочь вам. response - это параметр, который вы передаете своей функции, но не из postData. Если вы работаете с кодом, как предлагает Node Beginner Book, вы, вероятно, передаете ответ на свою функцию newuser полностью вниз от функции createServer, которая является частью http-модуля, который поставляется с Node.

Вы не можете определить переменную в обратном вызове, а затем использовать ее в обратном вызове, потому что Javascript лексически ограничен. Здесь Сообщение о переполнении стека на тему области Javascript. Первое видео Doug Crockford, которое я опубликовал, также имеет большое объяснение правил просмотра Javascript.

Javascript не обязательно асинхронный. Он просто предоставляет анонимные функции, которые являются закрытием, которые являются полезным инструментом для простой реализации асинхронной логики. Опять же, Node Beginner Book показывает хороший пример написания синхронного кода с Node (не то, что вы хотите), а затем переписываете его, чтобы сделать его асинхронным.