Please help me, with this async function [duplicate] - javascript

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.

promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.

When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.

pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064

The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.

Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});

There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}

I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.

Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}

In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.

When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17

The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});

promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}

This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}

You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

Related

how to get Boolean from Promise [duplicate]

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.
promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.
When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.
pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064
The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.
Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});
There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.
Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.
When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17
The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});
promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}
This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

JS fetch in do while loop [duplicate]

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.
promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.
When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.
pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064
The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.
Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});
There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.
Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.
When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17
The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});
promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}
This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

How can I get the value from Promise<pending> in JavaScript? [duplicate]

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.
promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.
When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.
pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064
The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.
Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});
There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.
Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.
When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17
The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});
promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}
This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

How to set variables after async function call returns [duplicate]

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.
promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.
When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.
pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064
The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.
Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});
There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.
Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.
When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17
The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});
promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}
This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

Is there a way to call an async function from outer scope? [duplicate]

I'm looking at this example from Angular's documentation for $q, but I think this probably applies to promises in general. The example below is copied verbatim from their documentation with their comment included:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1
I'm not clear how this works. If I can call .then() on the result of the first .then(), chaining them, which I know I can, then promiseB is a promise object, of type Object. It is not a Number. So what do they mean by "its value will be the result of promiseA incremented by 1"?
Am I supposed to access that as promiseB.value or something like that? How can the success callback return a promise AND return "result + 1"? I'm missing something.
promiseA's then function returns a new promise (promiseB) that is immediately resolved after promiseA is resolved, its value is the value of what is returned from the success function within promiseA.
In this case promiseA is resolved with a value - result and then immediately resolves promiseB with the value of result + 1.
Accessing the value of promiseB is done in the same way we accessed the result of promiseA.
promiseB.then(function(result) {
// here you can use the result of promiseB
});
As of ECMAScript 2016 (ES7, 2016), async/await is standard in JavaScript, which allows an alternative syntax to the approach described above. You can now write:
let result = await functionThatReturnsPromiseA();
result = result + 1;
Now there is no promiseB, because we've unwrapped the result from promiseA using await, and you can work with it directly.
However, await can only be used inside an async function. So to zoom out slightly, the above would have to be contained like so:
async function doSomething() {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
And, for clarity, the return value of the function doSomething in this example is still a promise - because async functions return promises. So if you wanted to access that return value, you would have to do result = await doSomething(), which you can only do inside another async function. Basically, only in a parent async context can you directly access the value produced from a child async context.
When a promise is resolved/rejected, it will call its success/error handler:
var promiseB = promiseA.then(function(result) {
// do something with result
});
The then method also returns a promise: promiseB, which will be resolved/rejected depending on the return value from the success/error handler from promiseA.
There are three possible values that promiseA's success/error handlers can return that will affect promiseB's outcome:
Return nothing → PromiseB is resolved immediately,
and undefined is passed to the success handler of promiseB
Return a value → PromiseB is resolved immediately,
and the value is passed to the success handler of promiseB
Return a promise → When resolved, promiseB will be resolved.
When rejected, promiseB will be rejected. The value passed to
the promiseB's then handler will be the result of the promise
Armed with this understanding, you can make sense of the following:
promiseB = promiseA.then(function(result) {
return result + 1;
});
The then call returns promiseB immediately.
When promiseA is resolved, it will pass the result to promiseA's success handler.
Since the return value is promiseA's result + 1, the success handler is returning a value (option 2 above), so promiseB will resolve immediately, and promiseB's success handler will be passed promiseA's result + 1.
pixelbits' answer is correct, and you should always use .then() to access the value of a promise in production code.
However, there is a way to access the promise's value directly after it has been resolved by using the following unsupported internal Node.js binding:
process.binding('util').getPromiseDetails(myPromise)[1]
WARNING: process.binding was never meant to be used outside of Node.js core and the Node.js core team is actively looking to deprecate it
doc: documentation deprecation of process.binding #22004
Migration from process.binding #22064
The .then function of promiseB receives what is returned from the .then function of promiseA.
Here promiseA is returning a number, which will be available as the number parameter in the success function of promiseB. Which will then be incremented by 1.
Parsing the comment a little differently than your current understanding might help:
// promiseB will be resolved immediately after promiseA is resolved
This states that promiseB is a promise, but it will be resolved immediately after promiseA is resolved. Another way of looking at this means that promiseA.then() returns a promise that is assigned to promiseB.
// and its value will be the result of promiseA incremented by 1
This means that the value that promiseA resolved to is the value that promiseB will receive as its successCallback value:
promiseB.then(function (val) {
// val is now promiseA's result + 1
});
There are some good previous answers and here is the ES6 arrow function version:
var something = async() => {
let result = await functionThatReturnsPromiseA();
return result + 1;
}
I am a slow learner of JavaScript promises. By default, all async functions return a promise, and you can wrap your result as:
(async () => {
//Optional "await"
await yourAsyncFunctionOrPromise()
.then(function (result) {
return result +1;
})
.catch(function (error) {
return error;
})()
})
From await (MDN):
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfilment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value
Read more about await and promises at MDN web documentation.
Actually, from the interactive (Node.js) prompt, one can just "await":
> y = new Promise((resolve, reject) => resolve(23));
Promise {
23,
[Symbol(async_id_symbol)]: 10419,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23
This is useful when experimenting at the REPL.
You can't do this in an "ordinary" function:
> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'
You can do this in an "async function", but that leaves you back holding a promise, not the value you want:
> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
<pending>,
[Symbol(async_id_symbol)]: 10571,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
In the Node.js REPL, to get a database connection that was the value of a promise, I took the following approach:
let connection
try {
(async () => {
connection = await returnsAPromiseResolvingToConnection()
})()
} catch(err) {
console.log(err)
}
The line with await would normally return a promise. This code can be pasted into the Node.js REPL or if saved in index.js. it can be run in Bash with
node -i -e "$(< index.js)"
which leaves you in the Node.js REPL after running the script with access to the set variable. To confirm that the asynchronous function has returned, you can log connection for example, and then you're ready to use the variable. One of course wouldn't want to count on the asynchronous function being resolved yet for any code in the script outside the asynchronous function.
When experimenting at an interactive prompt, one can access the value of a Promise by assigning the value to a global variable in the "then()" function, e.g.:
> promise = new Promise((resolve, reject) => resolve(17));
Promise {
17,
[Symbol(async_id_symbol)]: 7600,
[Symbol(trigger_async_id_symbol)]: 5,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
<pending>,
[Symbol(async_id_symbol)]: 7875,
[Symbol(trigger_async_id_symbol)]: 7600,
[Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17
In code, the idea seems to be to always force one to put the "follow up" code into the "then()" part (or, equivalently, if I understand, into the async/await pattern, which, again if I understand, gets rewritten into the "then()" pattern). I suppose the idea is that this prevents "blocking" the system, although providing no backdoor to get the value synchronously seems to me to be excessively paternalistic of the language designers.
Note, again from the interactive command line:
> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null
This is because the code in the "then()" has not run yet.
However, on the "next line" (at the interactive prompt) one can do:
> xyz
17
The MDN documentation helped me resolve this issue:
Promise.resolve()
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value);
});
If you need to need to go down multiple levels of the JSON object:
let promiseB = promiseA;
promiseB.then((value) => {
console.log(value?.key1.key2);
});
promiseA(pram).then(
result => {
//make sure promiseA function allready success and response
//do something here
}).catch(err => console.log(err)) => {
// handle error with try catch
}
This example I find self-explanatory. Notice how await waits for the result and so you miss the Promise being returned.
cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
You can easily do that using an async wait method in JavaScript.
Below is an example retrieving a WebRTC promise value using a timeout.
function await_getipv4(timeout = 1000) {
var t1 = new Date();
while(!window.ipv4) {
var stop = new Date() - t1 >= timeout;
if(stop) {
console.error('timeout exceeded for await_getipv4.');
return false;
}
}
return window.ipv4;
}
function async_getipv4() {
var ipv4 = null;
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
findIP.then(ip => window.ipv4 = ip);
return await_getipv4();
};

Categories