Bluebird 承诺一个重函数的结果
Bluebird Promising the result of a heavy function
我最近在 HAPI API 开发中经常使用 Bluebird。我刚刚 运行 遇到了我的第一个真正的问题,也许我的理解或天真让我难住了。
以下代码是我所面临的示例:-
var Promise = require('bluebird'),
stuff = require('../stuff');
module.exports = {
getSomething: function(request, reply) {
var p = Promise.resolve();
p = p.then(function() {
return db.find() //etc. etc.
});
p = p.then(function(resultFromPromise) {
//problems begin here
var data = stuff.doSomeReallyLongAndBoringFunction(resultFromPromise);
return data;
});
p.then(function(data) {
//no data here.
});
};
};
我已经评论了问题通常开始的地方。 stuff.doSomeReallyLongAndBoringFunction()
returns 一个对象(使用更多 promises concidently),它是我想要访问的这个对象,但是 //no data here
总是在数据 returns 之前触发。 stuff.doSomeReallyLongAndBoringFunction()
继续 运行 无论如何并成功完成,但在代码异步后,我不知道如何承诺返回该函数的 return 值。
谁能提供任何指导?请接受我对问题中任何幼稚的道歉!
感谢一如既往的帮助
NB 只是为了清楚起见,stuff.doSomeReallyLongAndBoringFunction()
并不是 return Promise 本身。虽然,我确实尝试过 return new Promise(reject, resolve) { });
手动换行。它只是一个使用 promises 本身(成功)获取数据的函数。
更新 1
stuff.doSomeReallyLongAndBoringFunction()
太大而无法直接 post,但它会做这样的事情:-
var Promise = require('bluebird'),
rp = require('request-promise');
module.exports = {
doSomeReallyLongAndBoringFunction: function() {
var p = Promise.resolve();
p = p.then(function() {
return db.find() //etc. etc.
});
p.then(function() {
rp(options).then(function(response){
//get some data from remote location
}).then(function(dataFromService) {
//do some jiggery pokery with said data
var marshalledData = dataFromService;
db.something.create({
Field: 'something'
}).exec(function(err, saved) {
return marshalledData;
});
});
}).catch(function(err) {
});
};
};
更新 2
谢谢贾斯汀的帮助。这是实际代码,也许这可能有帮助?
Promise.resolve()
.then(function() {
if(typeof utils.intTryParse(place) !== 'number') {
return foursquare.createPlaceFromFoursquare(sso, place, request, reply);
} else {
return { Place: { PlaceId: place }};
}
}).then(function(placeObj) {
console.log('Place set as', placeObj); //always returns undefined, despite function actually completing after async op...
});
如果您的 doSomeReallyLongAndBoringFunction
确实是 运行 异步的,那么按您的设置方式 运行 就没有意义。
编辑 - 这是您的代码看起来 运行ning 与重构版本的简单解释。它已被简化,因此您需要根据您的实际实施情况填写相关部分。
var Promise = require('bluebird');
function myAsync() {
setTimeout(function(){
return 'done sleeping';
}, 2000);
};
//The way your code is running
Promise.resolve()
.then(function(){
return 'hello';
})
.then(function(done){
console.log(done);
return myAsync(); //your error is here
})
.then(function(done){
console.log(done);
});
//refactored
Promise.resolve()
.then(function(){
return 'hello';
})
.then(function(done){
console.log(done);
return new Promise(function(resolve) {
setTimeout(function(){
resolve('done sleeping');
}, 2000);
});
})
.then(function(done){
console.log(done);
});
just for clarity, stuff.doSomeReallyLongAndBoringFunction()
does not return a Promise itself.
那是你的问题。因为它做一些异步的事情并且你想得到它的结果,所以它 应该 return 一个承诺。事实上,every 异步函数就是这种情况,尤其是 then
回调!应该是这样的
module.exports = {
doSomeReallyLongAndBoringFunction: function() {
return db.find()
// ^^^^^^
.then(function() {
return rp(options).then(function(response){
// ^^^^^^
//get some data from remote location
}).then(function(dataFromService) {
//do some jiggery pokery with said data
var marshalledData = dataFromService;
return db.something.create({
// ^^^^^^
Field: 'something'
}).execAsyc();
});
}).catch(function(err) {
});
}
};
您的 getSomething
方法存在同样的问题,应该如下所示:
var createPlace = Promise.promisify(foursquare.createPlaceFromFoursquare);
module.exports = {
getSomething: function(request) {
var p;
if (typeof utils.intTryParse(place) !== 'number')
p = createPlace(sso, place, request); // this returns a promise!
else
p = Promise.resolve({Place: {PlaceId: place}});
return p.then(function(placeObj) {
// ^^^^^^
console.log('Place set as', placeObj);
});
}
};
另请参阅 these generic rules 以了解 promise 开发。
doSomeReallyLongAndBoringFunction
需要看起来像这样:
doSomeReallyLongAndBoringFunction: function(param) {
var resolver = Promise.defer();
/*
* do some asynchronous task and when you are finished
* in the callback, do this:
*/
resolver.resolve(resultFromAsyncTask);
/*
*
*
*/
return resolver.promise;
}
我最近在 HAPI API 开发中经常使用 Bluebird。我刚刚 运行 遇到了我的第一个真正的问题,也许我的理解或天真让我难住了。
以下代码是我所面临的示例:-
var Promise = require('bluebird'),
stuff = require('../stuff');
module.exports = {
getSomething: function(request, reply) {
var p = Promise.resolve();
p = p.then(function() {
return db.find() //etc. etc.
});
p = p.then(function(resultFromPromise) {
//problems begin here
var data = stuff.doSomeReallyLongAndBoringFunction(resultFromPromise);
return data;
});
p.then(function(data) {
//no data here.
});
};
};
我已经评论了问题通常开始的地方。 stuff.doSomeReallyLongAndBoringFunction()
returns 一个对象(使用更多 promises concidently),它是我想要访问的这个对象,但是 //no data here
总是在数据 returns 之前触发。 stuff.doSomeReallyLongAndBoringFunction()
继续 运行 无论如何并成功完成,但在代码异步后,我不知道如何承诺返回该函数的 return 值。
谁能提供任何指导?请接受我对问题中任何幼稚的道歉!
感谢一如既往的帮助
NB 只是为了清楚起见,stuff.doSomeReallyLongAndBoringFunction()
并不是 return Promise 本身。虽然,我确实尝试过 return new Promise(reject, resolve) { });
手动换行。它只是一个使用 promises 本身(成功)获取数据的函数。
更新 1
stuff.doSomeReallyLongAndBoringFunction()
太大而无法直接 post,但它会做这样的事情:-
var Promise = require('bluebird'),
rp = require('request-promise');
module.exports = {
doSomeReallyLongAndBoringFunction: function() {
var p = Promise.resolve();
p = p.then(function() {
return db.find() //etc. etc.
});
p.then(function() {
rp(options).then(function(response){
//get some data from remote location
}).then(function(dataFromService) {
//do some jiggery pokery with said data
var marshalledData = dataFromService;
db.something.create({
Field: 'something'
}).exec(function(err, saved) {
return marshalledData;
});
});
}).catch(function(err) {
});
};
};
更新 2 谢谢贾斯汀的帮助。这是实际代码,也许这可能有帮助?
Promise.resolve()
.then(function() {
if(typeof utils.intTryParse(place) !== 'number') {
return foursquare.createPlaceFromFoursquare(sso, place, request, reply);
} else {
return { Place: { PlaceId: place }};
}
}).then(function(placeObj) {
console.log('Place set as', placeObj); //always returns undefined, despite function actually completing after async op...
});
如果您的 doSomeReallyLongAndBoringFunction
确实是 运行 异步的,那么按您的设置方式 运行 就没有意义。
编辑 - 这是您的代码看起来 运行ning 与重构版本的简单解释。它已被简化,因此您需要根据您的实际实施情况填写相关部分。
var Promise = require('bluebird');
function myAsync() {
setTimeout(function(){
return 'done sleeping';
}, 2000);
};
//The way your code is running
Promise.resolve()
.then(function(){
return 'hello';
})
.then(function(done){
console.log(done);
return myAsync(); //your error is here
})
.then(function(done){
console.log(done);
});
//refactored
Promise.resolve()
.then(function(){
return 'hello';
})
.then(function(done){
console.log(done);
return new Promise(function(resolve) {
setTimeout(function(){
resolve('done sleeping');
}, 2000);
});
})
.then(function(done){
console.log(done);
});
just for clarity,
stuff.doSomeReallyLongAndBoringFunction()
does not return a Promise itself.
那是你的问题。因为它做一些异步的事情并且你想得到它的结果,所以它 应该 return 一个承诺。事实上,every 异步函数就是这种情况,尤其是 then
回调!应该是这样的
module.exports = {
doSomeReallyLongAndBoringFunction: function() {
return db.find()
// ^^^^^^
.then(function() {
return rp(options).then(function(response){
// ^^^^^^
//get some data from remote location
}).then(function(dataFromService) {
//do some jiggery pokery with said data
var marshalledData = dataFromService;
return db.something.create({
// ^^^^^^
Field: 'something'
}).execAsyc();
});
}).catch(function(err) {
});
}
};
您的 getSomething
方法存在同样的问题,应该如下所示:
var createPlace = Promise.promisify(foursquare.createPlaceFromFoursquare);
module.exports = {
getSomething: function(request) {
var p;
if (typeof utils.intTryParse(place) !== 'number')
p = createPlace(sso, place, request); // this returns a promise!
else
p = Promise.resolve({Place: {PlaceId: place}});
return p.then(function(placeObj) {
// ^^^^^^
console.log('Place set as', placeObj);
});
}
};
另请参阅 these generic rules 以了解 promise 开发。
doSomeReallyLongAndBoringFunction
需要看起来像这样:
doSomeReallyLongAndBoringFunction: function(param) {
var resolver = Promise.defer();
/*
* do some asynchronous task and when you are finished
* in the callback, do this:
*/
resolver.resolve(resultFromAsyncTask);
/*
*
*
*/
return resolver.promise;
}