Meteor with Promises

I tried to get used to using promises but ran into problems when trying to use them in server-side code in the context of Meteor. This is the problem:

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
    p = function(){
      return new Promise(function(res,rej) {
        res("asd");
      });
    };
    p().then(function(asd){
      console.log("asd is " + asd);
      return "zxc"
    }).then(Meteor.bindEnvironment(function(zxc){
      console.log("zxc is " + zxc);
      return "qwe"
    })).then(function(qwe){
      console.log("qwe is " + qwe);
    });
  });
}

      

mvrx:bluebird

package installed

the code is also available on GitHub

Expected Result:

asd is asd         
zxc is zxc
qwe is qwe

      

Actual output:

asd is asd         
zxc is zxc
qwe is undefined

      

Removing the wrapper Meteor.bindEnvironment

fixes the problem, but I need it to be able to use collections inside callbacks

So what am I missing here? is it just not possible to use promises + Meteor this way or is there a bug?

What I am actually trying to accomplish is parallel pipelines, which have important partial results, but need synchronized completion. Something like that.

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup


    promises = [];

     step1 = function(input){
        return new Promise(function(res, rej){
          console.log(input + ":Step 1");
          res(input);
        });
      };
      step2 = function(input){
        return new Promise(function(res, rej){
          console.log(input + ":Step 2");
          res(input);
        });
      };
      step3 = function(input){
        return new Promise(function(res, rej){
          console.log(input + ":Step 3");
          res(input);
        });
      };
      slowIO = function(input){
        var inp = input;
        return new Promise( function(res,rej){
          setTimeout(function(){
            console.log(inp + ":SlowIO");
            res(inp);
          },Math.random()*20000);
        });
      };
      end = function(input){
        return new Promise(function(res,rej){
          console.log(input + ": done, commiting to database");
          res()
        });
      };

    for (var i = 0; i < 100; ++i) {
      promises.push(step1("pipeline-" + i).then(step2).then(slowIO).then(step3).then(end));
    };

    Promise.all(promises).then(function(){
      console.log("All complete")
    });



  });
}

      

+3


source to share


2 answers


(Update: I have filed the issue on github to see if it can be resolved. )

It looks like there is a problem with Meteor.bindEnvironment

using this method.

If it called a from outside Fiber

, it will not return its value.
Note the missing return

beforeFiber(runWithEnvironment).run()



The simple solution at the moment is to return a Promise instead of a result:

// when passed as a callback to `Promise#then`
//  allows it to resolve asynchronously
var asyncThen = function(fn){
  return function(arg){
    return new Promise(function(resolve, reject){
      fn(arg, resolve, reject);
    })
  };
};

Promise.resolve("asd").then(function(asd){
  console.log("asd is " + asd);
  return "zxc"
}).then(
  asyncThen(
    Meteor.bindEnvironment(function(zxc, resolve, reject){
      console.log("zxc is", zxc);
      resolve("qwe");
    })
  )
).then(function(qwe){
  console.log("qwe is " + qwe);
});

      

+3


source


A promise is just a way to write asynchronous code synchronously. If it's all after, why not use it Meteor.wrapAsync()

? In your case, you have a zxc

riding cowboy in his own fiber and who knows when he will be back. Bluebird works great and is very fast on the client, but I think the code is much cleaner using what Meteor gives you:



//*UNTESTED*//
asd = function() { return 'foo';};
asdSync = Meteor.wrapAsync(asd);
asdResult = asdSync();

qwe = function(input) {return input.reverse()};
qweSync = Meteor.wrapAsync(qwe);
qweResult = qweSync(asdResult); //should return 'oof'

      

+2


source







All Articles