2

I have a simple program in node.js, such as:

// CODE1
step1();
step2();
var o = step3();
step4(o);
step5();
step6();

this program is meant to be run in a stand-alone script (not in a web browser), and it is a sequential program where order of execution is important (eg, step6 needs to be executed after step5).

the problem is that step3() is an async function, and the value 'o' is actually passed to a given callback, so I would need to modify the program as follows:

// CODE2
step1();
step2();
step3( function (o) {
  step4(o);
  step5();
  step6();
})

it could make sense to call step4 from the callback function, because it depends on the 'o' value computed by step3. But step5 and step6 functions do not depend on 'o', and I have to include them in that callback function only to preserve the order of execution: step3, then step4, then step5 then step6.

this sounds really bad to me. this is a sequential program, and so I would like to convert step3 to a sync function.

how to do this? I am looking for something like this (eg using Q):

// CODE3
step1();
step2();
var deferred = Q.defer();
step3(deferred.resolve);
deferred.blockUntilFulfilled()     // this function does not exist; this is what i am looking for
var o = deferred.inspect().value
step4(o);
step5();
step6();

How to do this?

ps: there are advantages and disadvantages of using sync or async, and this is a very interesting discussion. however, it is not the purpose of this question. in this question, i am asking how can i block/wait until a promise (or equivalent) gets fulfilled. Please, please, please, do not start a discussion on whether sync/blocking is good or not.

4

1 回答 1

3

在原生 JavaScript 中将异步操作转换为同步操作是不可能的。有一些东西,比如 node-fibers(一个 C++ 插件)可以允许这样做,或者各种编译到 JS 的语言可以使异步操作看起来同步(基本上是通过将你的第一个代码块重写为第二个),但它在异步操作完成之前无法阻塞。

看到这一点的一种方法是注意 JavaScript 事件循环总是“运行到完成”,这意味着如果你有一系列语句,它们将始终保证一个接一个地执行,中间没有任何内容。因此,外部信息无法进入并告诉代码停止阻塞。假设你试图让它像这样工作:

stepA();
stepB();
while (global.operationIsStillGoing) {
  // do nothing
}
stepC();

global.operationIsStillGoing这永远不会奏效,因为由于 JavaScript 的运行到完成性质,在循环期间不可能更新任何内容while,因为这一系列语句尚未运行到完成。

当然,如果有人编写了一个修改语言的 C++ 插件,他们可以解决这个问题。但这不再是真正的 JavaScript,至少在 ECMAScript + 事件循环架构的普遍理解意义上。

于 2013-07-17T00:29:39.867 回答