Может ли Node реально вернуть значение из вызова функции перед завершением всех операций внутри самой функции?
У меня проблемы с пониманием того, как работает Node в отношении его параллельной обработки и возврата значений из вызовов функций.
К вашему сведению: приведенная ниже функция глотка просто создана в качестве примера для этого вопроса.
Возможно ли, что функция может вернуть поток до Read a large file
оператор завершил обработку (большой файл был полностью прочитан из файловой системы, и поток был добавлен), или Node достаточно умен, чтобы завершить все операторы перед возвратом?
function moveFiles(){
var gulp = require('gulp'),
stream = require('merge-stream')();
// Read a large file
stream.add(gulp.src('src/large-file.txt')
.pipe(gulp.dest('dest/'))
);
// Read a small file
stream.add(gulp.src('src/small-file.txt')
.pipe(gulp.dest('dest/'))
);
return (stream.isEmpty() ? null : stream);
}
1 ответ
Может ли Node реально вернуть значение из вызова функции перед завершением всех операций внутри самой функции?
Это сложный вопрос. Ответ - нет, в том смысле, что возвращение значения означает, что функция завершена, она извлечена из стека и больше никогда ничего не будет делать - если только она не была вызвана в другой раз, но суть в том, что этот конкретный вызов кончено.
Но самое сложное в том, что это функция, которая завершена, и это не значит, что она не может запланировать что-то еще в будущем. Через минуту все будет сложнее, но сначала очень простой пример.
function x() {
setTimeout(function () {
console.log('x1'));
}, 2000);
console.log('x2');
return;
console.log('x3');
}
Вот когда звонишь x()
затем он запланирует другую функцию для запуска через 2 секунды, затем он напечатает x2
и затем он вернется - в этот момент эта функция не сможет больше ничего делать для этого вызова.
Это означает, что x3
никогда не будет напечатан, но x1
в конечном итоге будет напечатан - потому что это еще одна функция, которая будет вызываться при срабатывании тайм-аута. Анонимная функция будет вызываться не потому, что x()
Функция может делать все что угодно после того, как вернется, но потому что ей удалось запланировать тайм-аут до ее возвращения.
Теперь, вместо того, чтобы просто планировать события в будущем, функция может вернуть обещание, которое будет решено через некоторое время. Например:
function y() {
console.log('y1');
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('message from y()');
}, 2000);
});
console.log('y2');
}
Теперь, когда вы бежите:
var promise = y();
что случится так y1
будет напечатано, новое обещание будет возвращено и y2
никогда не будет напечатан, потому что в этот момент y()
вернулся и больше ничего не может сделать. Но ему удалось запланировать тайм-аут, который разрешит обещание через две секунды.
Вы можете наблюдать это с:
promise.then(function (value) {
console.log(value);
});
Так что с этим примером вы можете увидеть, что в то время как y()
Сама функция возвращена и больше ничего не может делать, в будущем может быть вызвана другая (в данном случае анонимная) функция, которая завершит работу, которую y()
Функция инициирована.
Надеюсь, теперь понятно, почему это сложный вопрос. В некотором смысле функция не может ничего сделать после возврата. Но он мог бы запланировать некоторые другие функции, такие как тайм-ауты, обработчики событий и т. Д., Которые могут что-то делать после возврата функций. И если вещь, которую возвращает функция, является обещанием, то вызывающая сторона может легко наблюдать значение в будущем, когда оно будет готово.
Все примеры можно упростить, используя функции со стрелками, но я хотел бы четко указать, что это все отдельные функции, некоторые из них названы, а некоторые анонимны.
Для получения более подробной информации см. Некоторые из этих ответов:
- Подробное объяснение о том, как использовать обратные вызовы и обещания
- Объяснение того, как использовать обещания в сложных обработчиках запросов
- Объяснение того, что на самом деле является обещанием, на примере запросов AJAX
- Объяснение обратных вызовов, обещаний и способов доступа к данным, возвращаемым асинхронно