有希望的流星
Meteor with Promises
我一直在尝试养成使用 promises 的习惯,但是 运行 在 Meteor 的上下文中尝试在服务器端代码中使用它们时遇到了问题。这是问题所在:
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
包装器解决了问题,但我需要它以便能够在回调中使用集合
那么我在这里缺少什么?以这种方式使用 Promises + Meteor 是不可能的还是存在错误?
我实际上想要完成的是具有重要部分结果但需要同步结尾的并行管道。像这样。
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")
});
});
}
Promise 只是一种以同步方式编写异步代码的方式。
如果这就是您的全部目标,为什么不使用 Meteor.wrapAsync()
?在你的情况下,你有 zxc
骑牛仔在它自己的纤维中,谁知道它什么时候回来。 Bluebird 在客户端上很棒而且速度超快,但我认为使用 Meteor 为您提供的代码更清晰:
//*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'
(更新:I've logged an issue on github to see if it can be resolved.)
这样使用时 Meteor.bindEnvironment
似乎有问题。
If it's called from outside a Fiber
it won't return it's value. 注意Fiber(runWithEnvironment).run()
前少了return
目前一个简单的解决方案是 return Promise 而不是结果:
// 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);
});
我一直在尝试养成使用 promises 的习惯,但是 运行 在 Meteor 的上下文中尝试在服务器端代码中使用它们时遇到了问题。这是问题所在:
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
包装器解决了问题,但我需要它以便能够在回调中使用集合
那么我在这里缺少什么?以这种方式使用 Promises + Meteor 是不可能的还是存在错误?
我实际上想要完成的是具有重要部分结果但需要同步结尾的并行管道。像这样。
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")
});
});
}
Promise 只是一种以同步方式编写异步代码的方式。
如果这就是您的全部目标,为什么不使用 Meteor.wrapAsync()
?在你的情况下,你有 zxc
骑牛仔在它自己的纤维中,谁知道它什么时候回来。 Bluebird 在客户端上很棒而且速度超快,但我认为使用 Meteor 为您提供的代码更清晰:
//*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'
(更新:I've logged an issue on github to see if it can be resolved.)
这样使用时 Meteor.bindEnvironment
似乎有问题。
If it's called from outside a Fiber
it won't return it's value. 注意Fiber(runWithEnvironment).run()
return
目前一个简单的解决方案是 return Promise 而不是结果:
// 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);
});