Best practice: Promises reject/throw - promise

Background
This question suggests that using throw inside a promise function is effectively identical to calling the reject callback.
e.g. These are equivalent:
new Promise(function(resolve, reject) {
throw new Error("sadface"); // Using throw
}).catch(function(e) {
// ... handle error
});
new Promise(function(resolve, reject) {
reject(new Error("sadface")); // Using reject
}).catch(function(e) {
// ... handle error
});
Question
Obviously, if there's async code involved (such as an database or HTTP request), you can't use throw, since the stack has changed.
As a "best practice", should I then always use reject inside a promise to keep things consistent? Or should throw still be used under certain circumstances?

Obviously, if there's async code involved (such as an database or HTTP request), you can't use throw, since the stack has changed.
That's half the point of promises. Promises are throw safe, they let you use sync facilities like return and throw in asynchronous code.
Synchronous:
try {
return fn();
} catch (e) {
// handle error
return recover(e);
}
Promises:
fn().catch(recover);
Or more verbosely:
Promise.resolve().then(function() {
return fn();
}).catch(function(e) {
return recover(e);
});

Related

Synchronous Ajax Call in Angular

In my angular application, I have a scenario where i need to make looping over ajax calls. Scenario is as follows:
Based upon response from first request i need to initiate 2nd request, response from 2nd request would trigger 3rd request and so on. Wherever response does not meet certain criteria, loop needs to be broken.
Loop can go several times 10 or 20 based upon configured value.
Just want to make it synchronous. Anyone who can suggest approach to implement it ?
someList.forEach(async (value,index,arr)=> {
if(!isPrintingError)
{
let out = await this.someService.Print(someBuffer);
if(!out)
{
isPrintingError = true;
}
else {
console.log("Print successful");
}
}
}
Just have a look at Promises or async/await.
I'm not sure about how you want to do your ajax calls, and it would be great to have a small chunk of code.
But the idea is to do something like that
try {
const response1 = await this.apiCall1();
if (!response1) {
throw new Error('error1');
}
const response2 = await this.apiCall2();
if (!response2) {
throw new Error('error2');
}
// etc...
} catch (e) {
// logic in case of error
}
Also you can do it in a loop. But in order to give better help, i'll need some code
Try using RxJS Library, it will help you also in other different async stuff issues.
Using RxJS operators I'd take advantage of the Merge Operator.
More info here: RxJS Merge Operator
Thanks for your snippet. Here is how to break the loop in case of bad output
try {
someList.forEach(async (value, index, arr) => {
let output = await this.someService.Print(someBuffer);
if(!output) {
// break the loop
throw new Error('error');
} else {
console.log("Print successful");
}
}
} catch (e) {
// what to do if failed ?
}

Vuex store action from Promise to async/await

Currently I use promises in the store actions but want to convert it into async/await. This is an example of the store action with promises:
fetchActiveWorkspace (context, workspaceID) {
if (workspaceID) {
return this.$axios.get(`#api-v01/workspaces/workspace/${workspaceID}`)
.then(response => {
context.commit('setActiveWorkspace', response.data)
})
.catch(err => {
throw err
})
} else {
return Promise.resolve(true)
}
},
This fetchActiveWorkspace action is resolved in components because it returns promise. How can I convert this code snippet into a async/await structure and use it in components?
This is how I would try to translate it; take into account that as I have no access to the original code in full context, I cannot try it first-hand to make sure it works; but still, this is how you can use async/await with promises.
// 1. Mark the function as `async` (otherwise you cannot use `await` inside of it)
async fetchActiveWorkspace(context, workspaceID) {
if (workspaceID) {
// 2. Call the promise-returning function with `await` to wait for result before moving on.
// Capture the response in a varible (it used to go as argument for `then`)
let response = await this.$axios.get(`#api-v01/workspaces/workspace/${workspaceID}`);
context.commit('setActiveWorkspace', response.data);
}
// 3. I don't think this is necessary, as actions are not meant to return values and instead should be for asynchronous mutations.
else {
return true;
}
}
You can surround the function's body with try/catch in case you want to capture and handle exceptions. I didn't add it in order to keep things simple and because your promise-based code will just capture and re-throw the exception, without doing anything else.

Creating Promise that returns a 'thennable'. (or use Observable)

I have a function 'open' that I want to return a promise to the calling method, so that in my close function I resolve the Promise
open(config){
this.closePromise = new Promise()
return this.closePromise
}
close(closeArgs){
this.closePromise.resolve(closeArgs)
...
}
... so that my calling method gets a callback when my 'close' function is called like this :
myService.open(myData)
.then( closeArgs => console.log('closed'))
I am getting errors like 'Promise resolver undefined is not a function'
I am looking at the docs here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve but nothing seems to fit my needs. ( Im starting to wonder if I should just use an Observable in this scenario, as it may fit my situation better ).
Is this a bad scenario to be using a Promise or am I just doing it wrong ?
Thanks
A promise does not have a resolve method. You need to pass an executor callback to the new Promise constructor to gain access to the resolving function:
open(config) {
return new Promise(resolve => {
if (this.onClose) throw new Error("not yet closed, cannot open (again)");
this.onClose = resolve;
});
}
close(closeArgs) {
if (!this.onClose) throw new Error("not yet opened, cannot close (again)")
this.onClose(closeArgs);
this.onClose = null;
}

promise.try vs promise.resolve error handling

I've been looking at bluebird promises and how promise.try differs from a promise.resolve.then when an error is thrown. Firstly some code using promise.try where it throws a synchronous error
Promise.try(function() {
throw new Error('error');
}).catch(function(e) {
console.log(e);
});
secondly some code which throws a synchronous error on resolve
Promise.resolve().then(function() {
throw new Error('error');
}).catch(function(e) {
console.log(e);
});
As far as I'm aware they both behave the same. Is promise.try essentially a cleaner way of resolving the promise?
The docs says promise.try:
will catch all errors in their Promise .catch handlers instead of having to handle both synchronous and asynchronous exception flows.
In the case of the example given in the docs:
function getUserById(id) {
return Promise.try(function() {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
});
}
if the synchronous error is thrown the asynchronous code will never be reached. Would there be any difference if you put the code above in a promise.resolve().then(..)?
Any clarification/examples of promise.try will be much appreciated.
Adding to Bergi's answer: Promise.try is for those times you can't use Promise.method. The goal is to avoid cases where you have sync exceptions mixed with rejections.
Generally, whenever you're considering using Promise.try give Promise.method a spin.
var fn = Promise.method(function(){
// can throw or return here, and it'll behave correctly
});
Is roughly the same as:
var fn = function(){
return Promise.try(function(){
// can throw or return here, and it'll behave correctly
});
});
As far as I'm aware they both behave the same.
Yes, mostly. However, the .then(…) callback will be invoked asynchronously, while Promise.try is synchronously executing your function.
Is promise.try essentially a cleaner way of resolving the promise?
Yes, it does provide a cleaner (less confusing) notation. But it's more of an optimisation, because it doesn't create any Promise.resolve(undefined) in the first place.

what is the difference between thunk, futures, and promises?

There are wiki articles about them: (http://en.wikipedia.org/wiki/Futures_and_promises, http://en.wikipedia.org/wiki/Thunk_(delayed_computation)). But I am not sure what are the exact differences between the three as a programming language concept? Are futures and promises only applicable in concurrent programming?
An example of each, using javascript since everybody can read it.
Please don't use this code in production, use a real library, there are plenty of good ones.
var a, b, c, async_obj; // assume exist
// CommonJS - for reference purposes
try {
async_obj.asyncMethod(a, b, c, function (error1, result1) {
if (error1) {
console.error(error1);
} else {
console.log(result1);
}
});
} catch (ex1) {
console.error(ex1);
}
// Thunk - "a parameterless closure created to prevent the evaluation of an expression until forced at a later time"
function makeThunkForAsyncMethod (cb) {
return function () {
async_obj.asyncMethod(a, b, c, cb);
}
}
var my_thunk = makeThunkForAsyncMethod(function (error1, result1) {
if (error1) {
console.error(error1);
} else {
console.log(result1);
}
});
setTimeout(function () {
try {
my_thunk();
} catch (ex1) {
console.error(ex1);
}
}, 5e3);
// Promise - "a writable, single assignment container which sets the value of the future"
function makePromiseForAsyncMethod () {
var
future_then_cb,
future_catch_cb,
future
;
future = {
then: function (cb) {
future_then_cb = cb;
},
catch: function (cb) {
future_catch_cb = cb;
};
};
try {
async_obj.asyncMethod(a, b, c, function (error1, result1) {
if (error1) {
if (future_catch_cb) {
future_catch_cb(error1)
}
} else {
if (future_then_cb) {
future_then_cb(result1);
}
}
});
} catch (ex1) {
setTimeout(function () {
if (future_catch_cb) {
future_catch_cb(ex1);
}
});
}
return future;
}
// Future - "a read-only placeholder view of a variable"
var my_future = makePromiseForAsyncMethod();
my_future
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.error(error);
})
;
A Promise chain would be like the above contrived example, but it would work on collections and be more robust.
in functional programming, the most difference between thunk and promise is, thunk is pure while promise is impure.
function thunkDemo() {
return function(callback) {
asyncMethod(someParameter, callback);
};
}
function promiseDemo() {
return new Promise(function(resolve, reject) {
asyncMethod(someParameter, function(err, data) {
if(err) return reject(err);
resolve(data);
});
});
}
when thunkDemo is called, the asyncMethod will not be called until the inner method called, so thunkDemo is pure with no side affect.
when promiseDemo is called, it will call asyncMethod immediatly, which means, it's not pure.
Thunk is a general concept of a small function which is used only to adapt the call or prepare/modify it in some way and then redirect to the proper function. Things like promises, futures, closures, wrappers, stubs or implementations of the concept of virtual function tables in some OO languages (like C++) are just special use cases of thunks (thunks are often used to implement them).
These are quite broad terms, and their usage and interpretations vary with context. So a specific answer can only be given for a specific context.
In javascript promise libraries for example, the terms "deferred" and "promise" are used for what your linked wiki article refers to as "promise" and "future" respectively, in that a "deferred" is the interface for resolving or rejecting the value, and "promise" is the interface for reading it, with some more specifics that allow easily constructing new promises for dependent values, but not actually changing the original promise.
I just stumbled upon the JS library "co" (https://github.com/visionmedia/co).
It was the first time I heard of "thunks", and it seems to be using the term in a slightly different sense from slf's answer, and much more specific than your linked wiki as well. It is not a parameterless function that returns the value, it is a function accepting a callback that will call the callback with the value, often asynchronously.
In this specific library's case, thunks and promises are very close to each other: a promise is an object with a "then" method function that sets a callback for getting the value; a thunk is directly a function that sets a callback for getting the value.

Resources