New to Promises in serverside (Node js). Here is my question
I have code in FileA.js
incoming_form = client_services.pullForm('vsl_video1.mp4');
incoming_form.resolve().then(function(results) {
return console.log(results);
});
The incoming_form returns a Promise something like this in FileB.js
incoming_form () {
return Promise (function (resp, rej) {
var myArray = ['fudge', 'fgfdgdf'];
return resp(myArray);
});
}
How can I read my 'myArray' value in FileA.js? when I ran my FileA.js, I am getting this error
TypeError: incoming_form.resolve is not a function
I think you may have misunderstood the internal mechanisms by which Promise objects operate. This is how your code should look:
function incoming_form () {
return new Promise (function (resolve, reject) {
resolve(['fudge', 'fgfdgdf']);
});
}
incoming_form().then(function(results){
console.log ("Results" + results");
})
Note how the promise resolves internally, as opposed in a function call. Whenever a promise resolves, operation (and the arguments that the promise resolves with, in this case an array) is deferred to the closest subsequent then() clause.
Hope this clears some things up!
Use response.json() and then to return the value from promise object.
fetch('http://localhost:3100/comments')
.then(response => response.json())
.then(comments => console.log(comments));
Related
I know this is a common question asked, but I'm having a bit of an issue, trying to fire a function, ONLY when a promise has been returned. I also want to grab the value returned of the promise.
So I want to access an angular service, which seems to make an API call.
Wait for the promise to resolve.
Then store the promise returned as a value.
And then fire the function hello()
It seems when I fire run my code below, validPassengerId and hello()console.logs, before the promise has resolved.
How do I rewrite this code, to:
Wait for promise to resolve.
Then grab the value of the promise resolved - validPassengerId. (And then console.log it).
And then fire the function hello()?
function hello() {
console.log("hello");
};
const promise = new Promise((resolve, reject) => {
let validPassengerId = _funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag);
resolve(validPassengerId);
});
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
Assuming FindValidPassengerIdForBag returns a promise, you do not need to wrap it in another promise. You would use it like this:
_funnelBasketLuggageService
.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag)
.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
If validPassengerId is null with this code, then that must be what FindValidPassengerIdForBag is resolving its promise to. If you weren't expecting that, check the code of FindValidPassengerIdForBag or check that you're passing in valid parameters.
If in fact _funnelBasketLuggageService.FindValidPassengerIdForBag returns a promise, you solve this without creating your own Promise:
function hello() {
console.log("hello");
};
const promise = _funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag);
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
Explanation What you did was actually wrapping the Promise returned by FindValidPassengerIdForBag in another Promise that returns immediately.
If you absolutely have to wrap it in your own Promise, e.g. because you need to do some preprocessing, use .then instead of the return value of the function:
function hello() {
console.log("hello");
};
const promise = new Promise((resolve, reject) => {_funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag).then(id=>resolve(id));
});
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
I'm trying to rewrite promises function into async function
While my promises work
function boxColor (time) {
return new Promise ((res, rej) => {
setTimeout(() => {
res(box.style.backgroundColor = randomColor())
}, time)
})}
I can't make it work with async
async function newBoxColor(time) {
try {
setTimeout(() =>{
return box.style.backgroundColor = randomColor()
}, time)
} catch (error) {
throw error
} }
What is my mistake here?
The async keyword has two effects:
It makes the function return a promise which resolves to the value returned from the function (your function doesn't have a return statement so that is undefined; the return value of the arrow function passed to setTimeout is in a different function).
It allows you to use the await keyword inside that function to make it go to sleep while waiting for another promise to resolve
It is a tool to manage existing promises. It isn't helpful in converting a function which expects a callback to one which returns a promise.
You need to continue to use new Promise to get a Promise which resolves after setTimeout is done.
I have a asynchronous function sayHello() which is called inside greeting() function:
function greeting() {
let P = new Promise();
sayHello().then(function(){
//manipulate DOM
P.resolve();
}).catch(function(error)){
//manipulate DOM
P.reject();
});
return P;
}
I want greeting() to return a promise, so the caller would know when sayHello's work is finished. But this code doesn't seem to be correct, as it says Promise should have resolve and reject functions defined when being constructed. What should I do ?
Just return the Promise returned by sayHello():
function greeting() {
return sayHello().then(function(){
//manipulate DOM
}).catch(function(error)){
//manipulate DOM
});
}
The then method return a Promise.
Here's a simple fiddle illustrating this.
The other answers offer good solutions, but the actual reason you are seeing the error: Promise should have resolve and reject functions defined when being constructed. is the specific Promise implementation you are using. The latest version expects an "executor" function as the first argument when calling it:
new Promise(/* this is the executor: */ function (resolve, reject) { ... });
You can see the specification here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Older versions of Promise did not follow the same specification.
async function greeting() {
let response
try {
response = await sayHello()
} catch(err) {
response = err
}
return response
}
greeting().then(response => console.log(response))
function greeting2() {
return new Promise((resolve, reject) => {
sayHello().then(_ => {
//manipulate DOM
resolve()
}).catch(err => {
//manipulate DOM
reject()
})
})
}
greeting2().then(_ => console.log('something'))
I have a working promise chain:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
...
.then(resolve());
});
return promise;
}
This works great. It performs each of those function calls, waiting for each one to complete before firing off another. Each of those functions returns a promise, like so:
function syncCaesar(db) {
var promise = new Promise(resolve, reject) {
// do aysnc db calls, and whatnot, resolving/rejecting appropriately
}
return promise;
}
I need to run this chain on a series of databases, sequentially.
I've tried other solutions here, but they would fire off syncCats() all at once.
For instance:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(startSync(db));
}
Fires off syncCats(db[0]) and syncCats(db[1]) simultaneously.
Edit:
Performing startSync(dbs[0]).then(startSync(dbs[1])); acts the same.
Edit2: Also performs the same:
dbs.forEach(function(db) {
promise = promise.then(function() {
return startSync(db);
}
}
You're calling startSync and then passing its return value in to then. So naturally, if you do that twice, it's going to start the process twice in parallel.
Instead, pass in a function that doesn't call startSync until it's called:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(function() { startSync(db); });
});
or with ES2015:
let promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(_ => startSync(db));
});
Separately, three things jump out about startSync:
It starts all its operations in parallel, not sequentially
It exhibits the promise creation anti-pattern. There's no reason for startSync to create a new promise; it already has a promise it can work with
It ensures that its resolution value is undefined
If you really want the operations running in parallel like that, I suggest being more explicit about it:
function startSync(db) {
return Promise.all([
syncCats(db),
syncTrees(db),
syncCars(db)
])
.then(_ => undefined); // This does #3
}
...but you could also do to avoid the anti-pattern:
// Still run in parallel!
function startSync(db) {
return syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
.then(_ => undefined); // Does #3
}
If you meant for them to be sequential, you need to pass functions, not the result of calling them:
function startSync(db) {
return syncCats(db)
.then(_ => syncTrees(db))
.then(_ => syncCars(db))
.then(_ => undefined); // Again, does #3
}
If you made syncCats, syncTrees, and syncCars resolve their promises with db, like this:
function syncCats(db) {
return startSomethingAsync().then(_ => db);
}
...then it could be:
function startSync(db) {
return syncCats(db)
.then(syncTrees)
.then(syncCars)
.then(_ => undefined); // Only here for #3
}
...since each would receive db as its first argument.
Finally, if you don't need to force undefined as the promise resolution value, I suggest dropping that part from the above. :-)
With appreciation to T.J and Jaromanda, I was able to solve it by fixing how startSync() was resolved:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db)) // not correct way to call, see below
.then(syncCars(db))
...
.then(function() { resolve(); });
});
return promise;
}
Now, as T.J points out, the way each of the .then's is being called is incorrect. He explains it better in his answer. I'm being saved by some misunderstood database layer queueing. syncTrees() and syncCars() should be running in parallel.
If I understood it correctly, you will be having an array of databases and you want to sync them one by one i.e. sync for dbs[0], once that is complete sync for dbs[1], and so on. If that's correct you can do something like this.
var syncMultipleDBs = (dataBases) {
var db = dataBases.shift();
if (!db) {
return;
}
startSync(db).then(syncMultipleDBs.bind(null, dataBases));
};
syncsyncMultipleDBs(dbs.slice());
I hope this will help.
I have a code like this.. I want to fetch some contents and after all have loaded, do something.
So I use Promise.all and access resolved values later. but it is giving values but like Promise {' content here'}. (See console.log..)
I was gonna use Regex to extract it but then i check its type which isnt string but object with no keys? Why?
var request=require('request');
var urls=['someurl','someurl2','someurl3'];
var contents=[];
urls.forEach(function (u) {
contents.push(getContent(u) );
});
Promise.all(contents)
.then(function () {
// All should be loaded by now?
// Promises which are resolved are fulfiled, and values can be accessed later right?
contents.forEach(function (promise) {
var content = Promise.resolve(promise);
console.log(content); // Promise {'test'} ??
console.log(typeof content,Object.keys(content));
// object [] ???
});
}).
catch(function(err) {
//handle error here
});
function getContent(url) {
return new Promise ( function (resolve,reject) {
/** commented and stripped out for testing
request(url, function (err,response, data) {
if(err) {
reject(Error(err));
}
}); **/
resolve("test");
});
}
contents still only holds promises.
You can never directly extract the value of a promise; you can only consume it from a then() callback.
Instead, Promise.all() return a promise for the array of results.
Change your then() call to take that array as a callback parameter and use it directly.
First of all, you're accessing the results in the wrong way:
Promise.all(contents).then( function(data) {
// data holds an array with the return values of the promises
console.log(data);
});
Second thing: you're not creating a Promise correctly, essentially, you're never resolving them in your getContent() function, so you'll never get the data you want!
function getContent(url) {
return new Promise ( function (resolve,reject) {
request(url, function (err,response, data) {
if(err) {
// reject the promise in case of error
reject(Error(err));
} else {
// resolve the promise with the output you need
resolve(data);
}
});
When you call resolve(), the promise gets resolved and the input you give it is passed on.
When all promises you specified in Promise.all() are resolved, the callback will be executed and you'll be able to access the data returned with resolve().