using bluebird in my code , and I use promise.method to cover a original functions just like the api say.Then I write a function which return a promise,and use promise.method to cover it.Those two function return the same:
function () {
var ret = new Promise(INTERNAL);
ret._captureStackTrace();
ret._pushContext();
var value = tryCatch(fn).apply(this, arguments);
ret._popContext();
ret._resolveFromSyncValue(value);
return ret;
}
Is it ok to use promise.method to cover the function return a promise??
Building async APIs with errors
Yes, the point of Promise.method
is to make methods throw safe - for example if you have a method that looks like:
function foo(jsonStr){
var obj = JSON.parse(jsonStr);
return getApi(obj.endpoint);
}
It might throw
an error if passed an invalid object - so if you pass it an invalid string it'll throw (instead of reject). This means you have to guard against both thrown errors and rejected promises in your code and add a } catch(e){
and a .catch(function(e){
to your code.
This form of programming creates a weak and fragile API that differentiates synchronous and asynchronous errors and might (and will) create race conditions based on when errors happen. If a function might do something asynchronously it must always do it asynchronously. This is a core concept of developing asynchronous APIs - otherwise you end up with race conditions and other issues.
What Promise.method
does
Promise.method
basically wraps your method with a try/catch and converts thrown errors to rejections and returned values to fulfillments. If your function foo
was a Promise.method
it would always reject on errors instead of throwing. This fixes the race condition issue since your methods now always fail the same way.
var foo = Promise.method(function(jsonStr){
var obj = JSON.parse(jsonStr); // if this throws - you get a rejection
return getApi(obj.endpoint);
});
When not to use it
There are cases where you can get away with not using Promise.method
- for example when your method's body is in a promise chain or you're 100% sure it won't throw. In general - I find Promise.method
quite useful.
It also has the added benefit of letting you return plain values from promise returning methods and have them act consistently.
So should I wrap functions that return promises with it?
In general - yes. Exceptions apply and YMMV.