How to use promise schedule multiple function , should I have to make it like 2 way nest the callback?
on serverside I use nodejs and co make generateor,
then make it looks like below
co(function *() {
yield q1();
yield q2();
yield q3();
...
Is there some similar way syntax with promise ?
var q1 = function() {
return new Promise(function (fulfill, reject){
setTimeout(function(){
fulfill(console.log('q1'));
}, 100);
});
};
var q2 = function() {
return new Promise(function (fulfill, reject){
setTimeout(function(){
fulfill(console.log('q2'));
}, 100);
});
};
var q3 = function() {
console.log("done!");
};
1
q1().then(function() {
q2();
}).then(function() {
q3();
});
2
q1().then(function() {
q2().then(function() {
q3();
});
});
with the code you've got, you can simply do this
q1().then(q2).then(q3);
return the promise from the then callback like
var q1 = function() {
return new Promise(function(fulfill, reject) {
setTimeout(function() {
snippet.log('q1')
fulfill();
}, 1000);
});
};
var q2 = function() {
return new Promise(function(fulfill, reject) {
setTimeout(function() {
snippet.log('q2')
fulfill();
}, 1000);
});
};
var q3 = function() {
snippet.log("done!");
};
q1().then(function() {
return q2();
}).then(function() {
q3();
});
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Related
Why "then" in var test1 not show 1111111? But if just use resolve(); work fine. What wrong? How to do multiple promise requests at the same time?
window.testFunc = function() {
let _self = this;
this.test = function() {
_self.resolve();
};
return new Promise(function(resolve, reject) {
_self.resolve = resolve;
_self.reject = reject;
//this work fine
//resolve();
//this not work
setTimeout(function() {
_self.test();
}, 300);
});
};
let test1 = window.testFunc();
let test2 = window.testFunc();
test1.then(function(value) {
console.log(111111);
});
test2.then(function(value) {
console.log(222222);
});
this has the same value each time you call window.testFunc, so _self.test is the same property (which gets overwritten each time).
Use a local variable with a new object (let _self = {};) instead of a shared object.
window.testFunc = function() {
let _self = {};
_self.test = function () {
_self.resolve();
};
return new Promise(function (resolve, reject) {
_self.resolve = resolve;
_self.reject = reject;
//this work fine
//resolve();
//this not work
setTimeout(function(){
_self.test();
}, 300);
});
};
let test1 = window.testFunc();
let test2 = window.testFunc();
test1.then(function(value){
console.log(111111);
});
test2.then(function(value){
console.log(222222);
});
The following code gives me an error stating getConfigDetails...then is not a function. I want to return a promise from the function getConfigDetails if the isConfigLoaded variable is set to true otherwise keep calling it untill it is.
var getConfigDetails = function () {
if ($rootScope.isconfigloaded) {
configDetails.roles = $rootScope.orgConfig.roles.slice();
configDetails.departments = $rootScope.orgConfig.departments.slice();
configDetails.levels = $rootScope.orgConfig.levels.slice();
configDetails.designation = $rootScope.orgConfig.designation.slice();
return Promise.resolve();
} else {
setTimeout(function(){
getConfigDetails();
},200);
}
};
getConfigDetails().then(function(){});
You could do the following:
var getConfigDetails = new Promise(function(resolve, reject){
var ticker = setInterval(function(){
if ($rootScope.isconfigloaded) {
//the other stuff
clearInterval(ticker);
resolve();
}
}, 200);
});
You should be able to use it like getConfigDetails.then(function(){})
Notice its not a function though, just a promise. If you really want it to be a function do the following:
function getConfigDetails() {
return new Promise(function(resolve, reject){
var ticker = setInterval(function(){
if ($rootScope.isconfigloaded) {
//the other stuff
clearInterval(ticker);
resolve();
}
}, 200);
});
I am load HTML (external app) into an iFrame
I want to "do" something (callback) when an element becomes available in my iFrame. Here how I wrote it, and I'd like to write this with Promises instead:
function doWhenAvailable(selector, callback) {
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
callback && callback(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector, callback);
}, 1000);
}
}
Actually instead of using setTimeout, I'd like to use setInterval to repeat the "find element" until it's found and resolve the "promise".
No, you would not use setInterval, you just would wrap the timeout in a promise and drop the callback:
function wait(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
function whenAvailable(selector) {
var elt = $('#myiFrame').contents().find(selector);
if (elt.length)
return Promise.resolve(elt);
else
return wait(1000).then(function() {
return whenAvailable(selector);
});
}
Keeping your recursive style, it would have become something like that :
function doWhenAvailable(selector) {
var dfd = jQuery.Deferred();
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
return dfd.resolve(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector).then(function(e) {
dfd.resolve(e);
});
}, config[env].wrapper.timeOutInMs);
}
return dfd.promise();
}
But I would have tried to avoid recursive calls here
The general idea is to return a promise instead of receiving a callback.
Example:
var xpto = function(res) {
return new Promise((resolve, reject) => {
if(res > 0) resolve('Is greater');
else reject(new Error('is lower'));
});
}
So in your case:
function doWhenAvailable(selector) {
function work(callback) {
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
callback(elt);
}
}
return new Promise((resolve, reject) => {
console.warn("doWhenAvailable", selector)
setInterval(() => work(resolve), 1000);
})
}
Here:
function doWhenAvailable(selector) {
return new Promise(function(resolve, reject){
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
resolve(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector).then(function(data){
resolve(data);
});
}, config[env].wrapper.timeOutInMs);
}
}
}
And call your function like that:
doWhenAvailable("#elemId").then(function(elt){
//do what you want
});
Here is something wrong. All functions should be called synchronously. Could anyone give me a hint? I think that is an error in the for loop
Here is my code:
var radioValues = msg.options;
var cn = gotoReport()
.then(clickReport)
.then(clickReportFake)
.then(clickNext);
for (var i = 0; i < radioValues.length; i++){
cn = cn.then(clickOption(radioValues[i])).then(clickNext);
}
cn.then(clickSendToFacebook).then(clickFinish);
//all called functions look like that
function clickNext(){
return process(function(){
console.log("clickNext");
var next = $('button:contains("Weiter")');
$(next).click();
},3000);
}
function process(action, ms) {
var deferred = $.Deferred();
timer = setInterval(function() {
deferred.notify();
}, 1000);
setTimeout(function() {
clearInterval(timer);
action();
deferred.resolve();
}, ms);
// return deferred;
return deferred.promise();
}
function sleep(ms)
{
return(new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, ms);
}));
}
Here is the output
gotoReport
clickOption=option3
clickReport
clickReportFake
clickNext
clickNext
clickSendToFacebook
clickFinish
One major issue is here:
cn.then(clickOption(radioValues[i]))
You are not passing the clickOption function as argument to then -- you are invoking it. Instead do:
cn.then(clickOption.bind(null, radioValues[i]))
I some problems understanding how to use "q" (https://github.com/kriskowal/q) a promises library for javascript:
var delayOne = function() {
setTimeout(function() {
return 'hi';
}, 100);
};
var delayTwo = function(preValue) {
setTimeout(function() {
return preValue + ' my name';
}, 200);
};
var delayThree = function(preValue) {
setTimeout(function() {
return preValue + ' is bodo';
}, 300);
};
var delayFour = function(preValue) {
setTimeout(function() {
console.log(preValue);
}, 400);
};
Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).end();
this only returns undefined...
As wroniasty pointed out, you need to return a promise from each of those functions, but you should also abstract any callback oriented APIs (like setTimeout) as much as possible and use APIs that return promises instead.
In the case of setTimeout, Q already provides Q.delay(ms) which returns a promise that will be resolved after the specified number of milliseconds, perfect for replacing setTimeout:
var delayOne = function() {
return Q.delay(100).then(function() {
return 'hi';
});
};
var delayTwo = function(preValue) {
return Q.delay(200).then(function() {
return preValue + ' my name';
});
};
var delayThree = function(preValue) {
return Q.delay(300).then(function() {
return preValue + ' is bodo';
});
};
var delayFour = function(preValue) {
return Q.delay(400).then(function() {
console.log(preValue);
});
};
Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).done();
(note: end has been replaced with done)
The reason you get "undefined" is because the functions you are chaining are not returning anything:
var delayOne = function() {
setTimeout(function() {
return 'hi';
}, 100);
};
delayOne calls setTimeout, and returns nothing (undefined).
To achieve your goal you must use Q.defer:
var delayOne = function() {
var d = Q.defer();
setTimeout(function() {
d.resolve("HELLO");
}, 100);
return d.promise;
};
var delayTwo = function(preValue) {
setTimeout(function() {
alert(preValue);
},
400);
};
delayOne().then ( delayTwo );
http://jsfiddle.net/uzJrs/2/