Strange behaviour in javascript Promise - javascript

Considering code snippet below,
function one(){
var prm = new Promise(function(resolve,reject){
});
prm.customKey = function(){
}
return prm;
}
function two(){
return one().then(function(){
//something
});
}
Now calling the function two, returns a promise in which 'customKey' is missing
function three(){
return one();
}
But while doing the same thing in function three(without handling success using 'then'),
returns a promise which has 'customKey' in it.
Can someone clarify me whats really happening and why?

As you can see from "Mozilla Docs" then method returns new Promise (e.g: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then).
If you want to assign a function to retrieve / do something in resolve function do it like this:
var prm = new Promise((resolve, reject) => {
let customKeyFunction = () => {
console.log("I'm custom key function.");
};
resolve(customKeyFunction);
})
From now on you can call this function like that:
function two() {
return one().then(customKey => {
customKey();
})
}

Related

Add timeout function inside function before return value

This code is working fine , but I need to add something in timeout function before return in firstFunction()
function LastFunction(){
var answer = firstFunction();
console.log(answer)
}
function firstFunction() {
//Do something;
return somevalue
}
How to add timeout function inside function before return value ?
function firstFunction() {
setTimeout (function(){
var something = "something here"
},1000)
return something
}
You'll need to use Promises. Your code inside the setTimeout will be delayed but everything outside of it will continue to run synchronously.
function LastFunction(){
firstFunction().then(function(val) {
console.log(val)
return val
})
}
function firstFunction() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
var something = "something here"
resolve(something)
},1000)
})
return promise
}

javascript callback - execution of scripts is in random order

I have this problem - while executing this function
function(){
var after = function(){
server.executescript("scriptname")
};
var before = function (callback) {
server.executescript("scriptname2")
callback();
};
before(after);
}
execution of scripts is in random order and not as I would expect:
scriptname2
scriptname
what am I missing?
Thank you!
this seems to work
function(){
function after(){
server.executescript("scriptname");
}
function before(){
return new Promise((resolve, reject)=>{
server.executescript("scriptname2");
resolve();
});
}
before().then(after);
}
thank you all for participating!
The order you are seeing is the one expected:
var after = async function() {
await console.log("scriptname");
};
var before = async function (callback) {
await console.log("scriptname2");
callback();
};
before(after);
You first call the "before()" function which is going to call your "scriptname2".
Then you will call your "callback()" which is your "after()" function.
Which is going to call your "scriptname".

Listen for when promise resolves inside executor function

return new Promise(function(resolve, reject {
const to = setTimeout(function(){
});
});
imagine that I want to make sure resources are cleaned up from inside the executor function.
I would like to do something like this:
return new Promise(function(resolve, reject {
const to = setTimeout(function(){
});
this.finally(function(){
clearTimeout(to);
});
});
but this is not a available in a promise executor function.
Is there some way to clean up async resources in a promise executor?
I guess you could clean them up before call resolve/reject, but there are a few cases where that is harder.
Not sure if you need to clear the timeout after it fired but you could try the following:
var someTest = () => {
var t;
var p = new Promise(
(resole)=>{
t = setTimeout(resole,2000)
}
);
p.finally(
()=>console.log(t,clearTimeout(t))
)
return p;
}
someTest();
Or you could try the following:
var someTest = () =>
new Promise(
(resole)=>{
t = setTimeout(resole,2000)
}
).then(
result=>{
//clean up
return result
},
error=>{
//clean up
return Promise.reject(error)
}
);
From inside the promise executor, you can't get access to the promise. It hasn't been assigned yet to anything that your code can reach.
So, you have two options.
You can put your cleanup code outside the executor where you can access the returned promise with p.finally(). You will then have to also keep track of your resources outside the executor also (which is perhaps inconvenient).
You can replace the resolve() and reject() callbacks with your own stub that does your cleanup, then calls the actual resolve() or reject().
You can use a Deferred object which allows you to call resolve/reject from outside the promise executor thus giving you access to p.finally() and resolve() and reject() all in the same scope (which is really the source of the original challenge).
Here's an example of option #2:
return new Promise(function(rv, rj) {
// have to try/catch here because an execption will automatically reject
// without us having seen it
try {
// declare wrappers that should be called by code in this executor
// do not call rv() and rj() directly
function resolve(arg) {
finally();
rv(arg);
}
function reject(arg) {
finally();
rj(arg);
}
// cleanup code that is only ever called once
let finallyCalled = false;
function finally() {
if (!finallyCalled) {
clearTimeout(to);
finallyCalled = true;
}
}
const to = setTimeout(function(){
});
// elsewhere in this executor it should call resolve() or reject()
} catch(e) {
reject(e);
}
});
Here's an example of option #3.
Deferred objects are generally not recommended, but they do give you access to .finally(), resolve() and reject() all in the same scope which does make some things cleaner (like what you're trying to do).
First a simple promise wrapper that gives us a Deferred object:
// can be used as either:
// let d = Promise.Deferred();
// let d = new Promise.Deferred();
// d.then(...)
// d.resolve(x);
// d.finally(...)
Promise.Deferred = function() {
if (!(this instanceof Promise.Deferred)) {
return new Promise.Deferred();
}
let p = this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
this.then = p.then.bind(p);
this.catch = p.catch.bind(p);
this.finally = p.finally.bind(p);
}
Then, you could use it like this:
// usage
function yourFunction() {
let d = new Promise.Deferred();
const to = setTimeout(...);
// other code here that will call d.resolve() or d.reject()
// cleanup code
d.finally(function() {
clearTimeout(to);
});
return d.promise;
}
This OP describes one of the uglier snafus with Promises imo, but this might work:
return new Promise(function(resolve, reject {
const to = setTimeout(function(){
console.error('timed out');
reject('timed out');
});
doSomething(function(err, data){
if(!to._called){
resolve({to, data})
}
});
})
.then(function(v){
clearTimeout(v && v.to);
return v && v.data;
});
the problem with this solution is that callback in the then is called asynchronous, so it might be possible that the timer resolves in the interim? not sure.

Retrieve data from callback function if this function is of return type

function getPageDetails(callback,filterlink) {
var message=1+2;
callback(message,filterlink);
});
};
function test(message,filterlink)
{
var data=message+1;
return data
}
function test1(filterlink)
{
var testdata=getPageDetails(test,filterlink)
alert(testdata)
}
In this example, when I call test1(filterlist) method with a parameter and want to call a callback function. I did get any data in testdata variable. It should be 4 in alert. Can anyone help?
Your function getPageDetails isn't returning anything.
While executing callback(message, filterlink) you need to return it's result so var testdata will get the value assigned :
function getPageDetails(callback, b) {
[...]
return callback(...);
}
make use of promise , that will resolve your issue
let p1 = new Promise(
(resolve, reject) => {
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Promise started (<small>Async code started</small>)<br/>');
// This is only an example to create asynchronism
window.setTimeout(
function() {
// We fulfill the promise !
resolve(thisPromiseCount);
}, Math.random() * 2000 + 1000);
}
);
// We define what to do when the promise is resolved with the then() call,
// and what to do when the promise is rejected with the catch() call
p1.then(
// Log the fulfillment value
function(val) {
log.insertAdjacentHTML('beforeend', val +
') Promise fulfilled (<small>Async code terminated</small>)<br/>');
})
.catch(
// Log the rejection reason
(reason) => {
console.log('Handle rejected promise ('+reason+') here.');
});
Full info about : promise
If you return the callback like suggested in the comments and remove the }); in the first function it works.
I highly reccomend you to use the solution of Pranay Rana as it is much better. It's worth to invest in the understanding of promises if you work with js!
function getPageDetails(callback, filterlink) {
var message = 1 + 2;
return callback(message, filterlink);
}
function test(message, filterlink) {
var data = message + filterlink;
return data
}
function test1(filterlink) {
var testdata = getPageDetails(test, filterlink)
alert(testdata)
}
test1(1);

Return from a promise then()

I have got a javascript code like this:
function justTesting() {
promise.then(function(output) {
return output + 1;
});
}
var test = justTesting();
I have got always an undefined value for the var test. I think that it is because the promises are not resolved yet..there is a way to return a value from a promise?
When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails).
Source: https://web.dev/promises/#queuing-asynchronous-actions
To use a promise, you have to either call a function that creates a promise or you have to create one yourself. You don't really describe what problem you're really trying to solve, but here's how you would create a promise yourself:
function justTesting(input) {
return new Promise(function(resolve, reject) {
// some async operation here
setTimeout(function() {
// resolve the promise with some value
resolve(input + 10);
}, 500);
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
Or, if you already have a function that returns a promise, you can use that function and return its promise:
// function that returns a promise
function delay(t) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, t);
});
}
function justTesting(input) {
return delay(100).then(function() {
return input + 10;
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
What I have done here is that I have returned a promise from the justTesting function. You can then get the result when the function is resolved.
// new answer
function justTesting() {
return new Promise((resolve, reject) => {
if (true) {
return resolve("testing");
} else {
return reject("promise failed");
}
});
}
justTesting()
.then(res => {
let test = res;
// do something with the output :)
})
.catch(err => {
console.log(err);
});
Hope this helps!
// old answer
function justTesting() {
return promise.then(function(output) {
return output + 1;
});
}
justTesting().then((res) => {
var test = res;
// do something with the output :)
}
I prefer to use "await" command and async functions to get rid of confusions of promises,
In this case I would write an asynchronous function first,
this will be used instead of the anonymous function called under "promise.then" part of this question :
async function SubFunction(output){
// Call to database , returns a promise, like an Ajax call etc :
const response = await axios.get( GetApiHost() + '/api/some_endpoint')
// Return :
return response;
}
and then I would call this function from main function :
async function justTesting() {
const lv_result = await SubFunction(output);
return lv_result + 1;
}
Noting that I returned both main function and sub function to async functions here.
Promises don't "return" values, they pass them to a callback (which you supply with .then()).
It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation.
Then in your then code you can reference someObject to do what you want.
I think what the original poster wants is to return an unwrapped value from a promise without actually returning another promise. Unless proven otherwise, I'm afraid this is not possible outside of a then() or async/await context. You always get a promise no matter what.
You need to make use of reference data type like array or object.
function foo(u,n){
let result = [];
const userBrands = new Promise((res, rej)=> {
res(['brand 1', 'brand 3']);
})
userBrands.then((ub)=>{
return new Promise((res, rej) =>{
res([...ub, 'brand 4', 'brand 5']);
})
}).then(response => {
return result.push(...response);
});
return result;
};
foo();
You cannot return value after resolving promise. Instead call another function when promise is resolved:
function justTesting() {
promise.then(function(output) {
// instead of return call another function
afterResolve(output + 1);
});
}
function afterResolve(result) {
// do something with result
}
var test = justTesting();

Categories

Resources