How to wait for a promise to be resolved?

2019-03-22 14:32发布

问题:

I'm dealing with a NodeJs framework that requires a certain function to be synchronous, but I need to retrieve a value that can only be accessed asynchronously. In a perfect world, I would be able to return a promise, but I can't.

As a quick-and-dirty solution, I created the following method:

exports.synchronizePromise = function(promise) {
    var value;
    promise.then(function(promiseValue) {
        value = promiseValue;
    });
    while (!value) {} // Wait for promise to resolve
    console.log("DONE: " + value); // Never reached
    return value;
};

But I get an error. Is there any way to accomplish what I need?

回答1:

Given that node is by default only single threaded there isn't really an easy way to solve this. There is one though. Bases on generators/fibers you can add a sort of concurrent execution to node. There is a waitfor implementation based on that.



回答2:

In Q if you have a resolved promise you can just take the value with inspect

exports.synchronizePromise = function(promise) {
  var i = promise.inspect();
    if (i.state === "rejected") {
      throw i.reason;
    } else if (i.state === "fulfilled") {
      return i.value;
    } else {
      throw new Error("attempt to synchronize pending promise")
    }
};

However if the promise is pending, it is truly asynchronous and your question doesn't then make sense and the function will throw an error.



回答3:

Promises are asynchronous. They represent a future value--a value available in 1ms, or 1 minute, or 1 day, or 1 year in the future, or never. By definition, there is no way to "force" them to resolve, other than a time machine.

If you have upstream logic which is built on the premise of synchronicity, but for whatever reason things it was depending on are now asynchronous, you have to refactor that upstream component to operate asynchronously as well. There is no other alternative.

If your framework "requires a certain function to be synchronous" when that function is not or cannot be synchronous, then the framework is poorly designed and unusable, or at least not usable for your problem.