-1

I need the result of a promise in the next line of code, but I can't just include it in the .then of the promise as the containing function completes and then its to late.

Basically I have a bit of synchronous code and a but of async code. I need to have the sync code pause and wait for the the async to finish before continuing.

function outer () {

  it('1', function () {});
  it('2', function () {});
  it('3', function () {});

  var result = null;
  promise.then(function (r) {
    result = r;
  });

  // How do I wait for result to be
  // valid?

  if (result === true) {
    it('4', function () {});
  }
}

Please note, I can not do this...

function outer () {

  it('1', function () {});
  it('2', function () {});
  it('3', function () {});

  promise.then(function (result) {
    // It's to late to call it. The outer function is done
    // the it call here causes a throw
    if (result === true) {
      it('4', function () {});
    }
  });
}
Justin808
  • 20,859
  • 46
  • 160
  • 265
  • 1
    This is more or less a duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/q/23667086/218196) – Felix Kling May 07 '15 at 00:49
  • @FelixKling- I know why, I know what a promise is, I use then a lot, all over the place. I'm just trying to learn how to use it in a bit of code that is sync. – Justin808 May 07 '15 at 00:52
  • 1
    Code that expects everything to be sync cannot call async code. That's just how it is and that's the whole point of the other question. – Felix Kling May 07 '15 at 00:52
  • @Justin808 - at this point, I think maybe you should delete this question and start a new question that focuses on how you use a specific version of Jasmine with promises and async results. That would direct your question in a much better way and if you tag it with Jasmine and async, you will hopefully attract people that know more about that specific issue. – jfriend00 May 07 '15 at 01:19
  • @jfriend00 - I've tried. SO changed I guess, they won't let me delete it with answer. So I'm stuck with a -2 and a useless question is on SO. I flagged it to try and have it deleted, we'll see. – Justin808 May 07 '15 at 01:26
  • @Justin808 - or you could just accept one of the answers since they answered your question about how to wait for an async result (you can't) and then ask a new question about your Jasmine-specific stuff. Per [numerous meta questions](http://meta.stackoverflow.com/questions/256556/unable-to-delete-question-with-answers-even-with-dialog-that-says-it-has-answers), SO generally doesn't want questions deleted that have answers. – jfriend00 May 07 '15 at 01:41

2 Answers2

0

You can't. Promises are async. Javascript does not have a means to "pause" execution until an async operation is done. It just doesn't have that capability. So your async operations will not have delivered their result by the next line of code. You will need to restructure your code so that all the code that you want to run after the result is known is in the .then() handler.

promise.then(function (r) {
    if (r === true) {
        it('4', function () {});
    }
});

If you encounter a problem with putting the code inside the .then() handler, then that code also needs to be fixed because that is the only place you can use the async result. So, based on your comments, that's what you need to do. You have to learn how to use Jasmine properly with async results so that you can put the code inside the .then() handler without it throwing.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Great, How do I go about doing what I need to do then? As you can see when I move the code into the .then() it throws. If you notice, I have your example code already in my question saying I can't do that. – Justin808 May 07 '15 at 00:48
  • 1
    @Justin808 - Why can't you put it in the `.then()` handler? That's the only place it can be so you will have to explain what problem you're having when it is put there and then we can help you solve THAT problem. – jfriend00 May 07 '15 at 00:48
  • I get a "throw new Error('jasmine.Suite() required');". The 4th it call happen to late when it's inside the .then(). – Justin808 May 07 '15 at 00:49
  • 1
    @Justin808 - then you need to attack that problem and understand why you're having that problem. I'm quite sure that Jasmine can be used with async operations. You will have to learn how to do that. Perhaps this is a starting point [Testing Asynchronous Javascript w/ Jasmine 2.0.0](http://blogs.lessthandot.com/index.php/webdev/uidevelopment/javascript/testing-asynchronous-javascript-w-jasmine/). – jfriend00 May 07 '15 at 00:50
  • @Justin808: So, somehow your setup doesn't seem to work with Jasmine. You should provide more context and investigate that specific error. The general answer to your general question is that you have to access the value inside the `.then` handler. – Felix Kling May 07 '15 at 00:50
  • @Justin808 - if you Google search "async Jasmine promises", there are lots of articles about using Jasmine with async operations. – jfriend00 May 07 '15 at 00:53
  • @jfriend00 - I did google, thats why I'm here. I use promises inside the test just fine. I need to just not run a whole test in a specific situation. That is not run the `it` at all. Normally I can wrap the `it` in and if and its not a problem. The issue this time is I need info based on a promise. – Justin808 May 07 '15 at 00:58
  • @Justin808 - I don't know Jasmine myself, but there are lots of examples of testing async results inside `.then()` handlers in this article: http://blogs.lessthandot.com/index.php/webdev/uidevelopment/javascript/testing-asynchronous-javascript-w-jasmine/ – jfriend00 May 07 '15 at 01:00
  • @Justin808: Maybe Jasmine controls the timers and allows you to resolve the next tick synchronously (like Jest does)? But again, you are asking a pretty generic question and the generic answer is that it is not possible. If you have a specific problem with Jasmine, you should ask about that instead. – Felix Kling May 07 '15 at 01:02
  • @Justin808 - per this article https://github.com/mhevery/jasmine-node/issues/267, it sounds like the `it()` function accepts a callback and if you pass that callback to it, it will not execute the test until that callback has been called. – jfriend00 May 07 '15 at 01:04
  • In most testing frameworks, `it( "does something", function (done) { doSomething().then(function ( result ) { expect(result).toBeDefined(); done(); }); });` works just fine. This is not a `Promise` question, but rather a "which libraries for which purposes have which forms of concurrency". For the record, Gulp tasks can be made to work the same way (if you don't use / return streams), and the third argument of `Transform` stream methods behave similarly, as well. – Norguard May 07 '15 at 01:08
  • @Norguard - If I move the promise to *inside* the it, then yes, thing work. But that mean's 1/2 the time I have a test (it) running that will pass that does nothing. Its a false positive. I need to wrap the `it` in the if. – Justin808 May 07 '15 at 01:11
0

Your constraint makes this question impossible to answer. It must go into the then callback. If doing so throws, then that is because whatever code you have outside of your snippet is also written incorrectly.

carc
  • 63
  • 2
  • 8