問題描述
我無法理解 Node 在并行處理和函數(shù)調(diào)用返回值方面的操作方式.
I'm having trouble understanding how Node operates regarding it's parallel processing and returning values from function calls.
僅供參考:下面的 gulp 函數(shù)僅作為此問題的示例而創(chuàng)建.
FYI: The gulp function below is merely created as an example for this question.
在Read a large file
語句完成處理(大文件已從文件系統(tǒng)完全讀取并添加流)之前,該函數(shù)是否可能返回流,還是 Node 足夠聰明,可以在返回之前完成所有語句?
Is it possible that the function could return the stream before the Read a large file
statement has finished processing (the large file has been fully read from the file system and the stream has been added), or is Node smart enough to complete all statements before returning?
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);
}
推薦答案
在完成函數(shù)本身的所有操作之前,Node 是否可以從函數(shù)調(diào)用中返回一個值?
Could Node feasibly return a value from a function call before completing all operations within the function itself?
這是一個棘手的問題.答案是否定的,在某種程度上,返回一個值意味著函數(shù)已完成執(zhí)行,它從堆棧中取回并且它永遠不會再做任何事情 - 當然除非它在另一個時間被調(diào)用,但關(guān)鍵是這個特定的調(diào)用結(jié)束了.
This is a tricky question. The answer is no, in a way that returning a value means that the function is finished executing, it's taken back from the stack and it will never do anything again - unless it's invoked another time of course, but the point is that this particular invocation is over.
但棘手的部分是 函數(shù) 已完成執(zhí)行,這并不意味著它不能安排將來??發(fā)生其他事情.稍后會變得更復(fù)雜,但首先是一個非常簡單的示例.
But the tricky part is that it's the function that's finished executing and it doesn't mean that it couldn't schedule something else to happen in the future. It will get more complicated in a minute but first a very simple example.
function x() {
setTimeout(function () {
console.log('x1'));
}, 2000);
console.log('x2');
return;
console.log('x3');
}
這里當你調(diào)用 x()
然后它會安排 another 函數(shù)在 2 秒后運行,然后它會打印 x2
然后它將返回 - 此時此函數(shù)無法再為該調(diào)用執(zhí)行任何其他操作.
Here when you call x()
then it will schedule another function to run after 2 seconds, then it will print x2
and then it will return - at which point this function cannot do anything else ever again for that invocation.
這意味著 x3
永遠不會被打印,但 x1
最終會被打印 - 因為它是另一個在超時觸發(fā)時將被調(diào)用的函數(shù).匿名函數(shù)將被調(diào)用不是因為 x()
函數(shù)在返回后可以做任何事情,而是因為它設(shè)法在返回之前安排了超時時間.
It means that x3
will never get printed, but x1
will eventually get printed - because it's another function that will be called when the timeout fires. The anonymous function will get called not because the x()
function can do anything after it returns, but because it managed to schedule the timeout before it returned.
現(xiàn)在,一個函數(shù)可以返回一個承諾,該承諾將在一段時間后得到解決,而不是僅僅安排未來發(fā)生的事情.例如:
Now, instead of just scheduling things to happen in the future, a function can return a promise that will get resolved some time later. For example:
function y() {
console.log('y1');
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('message from y()');
}, 2000);
});
console.log('y2');
}
現(xiàn)在,當你運行時:
var promise = y();
將會發(fā)生的是 y1
將被打印,一個新的承諾將被返回并且 y2
將永遠不會被打印,因為此時 y()
返回并且不能做任何其他事情.但它設(shè)法安排了一個超時,將在兩秒后解決這個承諾.
what will happen is that y1
will get printed, a new promise will get returned and y2
will never get printed because at that point y()
returned and cannot do anything else. But it managed to schedule a timeout that will resolve the promise after two seconds.
您可以通過以下方式觀察它:
You can observe it with:
promise.then(function (value) {
console.log(value);
});
所以通過這個例子你可以看到,雖然 y()
函數(shù)本身返回并且不能做任何其他事情,但將來可以調(diào)用其他一些(在這種情況下是匿名的)函數(shù)并完成y()
函數(shù)已啟動的作業(yè).
So with this example you can see that while the y()
function itself returned and cannot do anything else, some other (anonymous in this case) function can be called in the future and finish the job that the y()
function has initiated.
所以我希望現(xiàn)在清楚為什么這是一個棘手的問題.在某種程度上,一個函數(shù)在返回后不能做任何事情.但它可以安排一些其他函數(shù)作為超時、事件處理程序等,這些函數(shù)可以在函數(shù)返回后執(zhí)行某些操作.如果函數(shù)返回的東西是一個承諾,那么調(diào)用者可以很容易地在它準備好時觀察到未來的值.
So I hope now it's clear why it's a tricky question. In a way a function cannot do anything after returning. But it could have scheduled some other functions as timeouts, event handlers etc. that can do something after the functions returns. And if the thing that the function returns is a promise then the caller can easily observe the value in the future when it's ready.
所有示例都可以通過使用箭頭函數(shù)來簡化,但我想明確指出這些都是單獨的函數(shù),其中一些是命名的,一些是匿名的.
All of the examples could be simplified by using the arrow functions but I wanted to make it explicit that those are all separate functions, some of them are named, some are anonymous.
有關(guān)更多詳細信息,請參閱其中一些答案:
For more details see some of those answers:
- 詳細說明如何使用回調(diào)和承諾
- 解釋如何在復(fù)雜的請求處理程序
- 在AJAX 請求示例
- 對回調(diào)、承諾和如何做的解釋訪問異步返回的數(shù)據(jù)
這篇關(guān)于在完成函數(shù)本身的所有操作之前,Node 是否可以從函數(shù)調(diào)用中返回一個值?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!