流星与应许 [英] Meteor with Promises

查看:68
本文介绍了流星与应许的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图养成使用Promise的习惯,但是在尝试在Meteor上下文中的服务器端代码中使用它们时遇到了问题.这是问题所在:

I've been trying to get into the habit of using promises but ran into problems while 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软件包已安装

代码也可从 GitHub

预期输出:

asd is asd         
zxc is zxc
qwe is qwe

实际输出:

asd is asd         
zxc is zxc
qwe is undefined

删除Meteor.bindEnvironment包装器可以解决此问题,但是我需要它,以便能够在回调中使用Collections

Dropping the Meteor.bindEnvironment wrapper fixes the problem, but i need it in order to be able to use Collections inside the callbacks

那么我在这里想念什么?不能以这种方式使用Promises + Meteor还是有bug?

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

我实际上想要完成的是并行管道,该管道具有重要的部分结果,但需要同步的结尾.像这样的东西.

What i'm actually trying to accomplish is parallel pipelines that have important partial results but need a synchronized ending. Something like this.

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")
    });



  });
}

推荐答案

(更新:我已经在github上记录了一个问题,看是否可以解决.)

以这种方式使用时,似乎Meteor.bindEnvironment存在问题.

Looks like there's a issue with Meteor.bindEnvironment when used this way.

如果从Fiber外部调用不会返回它的值. Fiber(runWithEnvironment).run()

If it's called from outside a Fiber it won't return it's value. Notice the missing return before Fiber(runWithEnvironment).run()

目前一种简单的解决方案是返回Promise而不是结果:

A simple solution for the moment is to return a Promise instead of the 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);
});

这篇关于流星与应许的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆