javascript node.js in a stand-alone script, block/wait on a promise

落爺英雄遲暮 提交于 2019-12-11 00:30:27

问题


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.


回答1:


It's impossible to turn an async operation into a sync operation in vanilla JavaScript. There are things like node-fibers (a C++ add-on) that will allow this, or various compile-to-JS languages that will make the async operations look sync (essentially by rewriting your first code block to the second), but it is not possible to block until an async operation completes.

One way to see this is to note that the JavaScript event loop is always "run to completion," meaning that if you have a series of statements, they will always be guaranteed to execute one after the other, with nothing in between. Thus there is no way for an outside piece of information to come in and tell the code to stop blocking. Say you tried to make it work like so:

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

This will never work, because due to the run-to-completion nature of JavaScript, it is not possible for anything to update global.operationIsStillGoing during the while loop, since that series of statements has not yet run to completion.

Of course, if someone writes a C++ addon that modifies the language, they can get around this. But that's not really JavaScript any more, at least in the commonly understood sense of ECMAScript + the event loop architecture.



来源:https://stackoverflow.com/questions/17689151/javascript-node-js-in-a-stand-alone-script-block-wait-on-a-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!