Why promis only works in the last variable? - javascript

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);
});

Related

return promise from a function called in settimeout

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);
});

Promise returning unexpectedly

I have the following:
return indexedDbClient.getStorageUsedInGb().then(function (storageUsedInGb) {
var evictedMediaGuids = [];
storageUsedInGb = parseFloat(storageUsedInGb);
if (storageUsedInGb > storageQuotaInGb) {
return new Promise(function(resolve, reject){
const store = database.transaction(storeName, "readwrite").objectStore(storeName);
(function loop(storageUsedInGb) {
if (storageUsedInGb <= storageQuotaInGb) {
resolve({
evictedMediaGuids: evictedMediaGuids,
shouldStopStoring: false
});
} else {
const latestMediaRequest = store.getAll();
latestMediaRequest.onsuccess = function (event) {
const allData = event.target.result;
const targetEntry = allData[0];
const deleteRequest = store.delete(targetEntry.media.guid);
evictedMediaGuids.push(targetEntry.media.guid);
deleteRequest.onsuccess = loop.bind(null, storageUsedInGb - event.target.media.size / 1024 / 1000 / 1000);
deleteRequest.onerror = reject;
}
latestMediaRequest.onerror = reject;
}
})(storageUsedInGb); // call immediately
})
} else {
return Promise.resolve({
evictedMediaGuids: evictedMediaGuids,
shouldStopStoring: false
});
}
}).then(function (storeObject) {
// do stuff to object
return Promise.resolve(storeObject)
});
The idea is that loop(storageUsedInGb) forces the resolution to wait for the return; however handleStoreObject gets invoked immediately after loop - with no sign of the latestMediaRequest onsuccess handler being invoked. What am I doing wrong?
I am using bluebird in case it matters.

jquery deferred and promise in a loop

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]))

Client PNG compression using javascript like pngcrush?

I'm developing HTML5 apps.
When user uploads image from their mobile, the size was too large.
I want to compress the image as PNG like the pngcrush way.
Is there any good way to choice on the frontend (like a javascript library)?
Or is it possible to port the pngcrush library to javascript?
There are a few projects out there which seem to be based around the idea of using emscripten (a LLVM-to-JavaScript compiler) to actually compile the source code from pngcrush to working JavaScript for the browser.
JavaScript-Packer/PNGCrush.html - based on pngcrush-1.7.27
richardassar/pngcrush.js - based on pngcrush-1.7.27
pngcrush-crushed - based on pngcrush-1.7.58
The version for pngcrush-1.7.27 is currently the only one that doesn't seem to produce corrupted images for me. I put together an example which uses promises here: http://plnkr.co/edit/iLpbOjlYiacR04oGdXSI?p=preview
Here's a basic usage example:
var instance = new pngcrush();
instance.exec(inputFile, function (stdoutEvent) {
console.log(stdoutEvent.data.line);
}).then(function (doneEvent) {
var outputFile = new Blob([doneEvent.data.data], { type: 'image/png' });
// do something with the outputFile
});
Here are the contents of the pngcrush-class.js file from the above plunker for reference:
(function(exports) {
var noop = function () {};
function pngcrush () {
this.callbacks = {
'error': [],
'done': [],
'start': [],
'stdout': []
};
}
pngcrush.prototype.exec = function (file, notify) {
var self = this;
if (this.execPromise) {
return this.execPromise.catch(noop).then(function () {
return self.exec(file, notify);
});
}
if (file.type !== 'image/png') {
return Promise.reject(file);
}
var promise = this.execPromise = this.readAsArrayBuffer(file).then(function (event) {
var arrayBuffer = event.target.result;
return self.initWorker().then(function (worker) {
var done = new Promise(function (resolve, reject) {
var offDone, offError, offStdout;
offDone = self.once('done', function (event) {
offError();
offStdout();
resolve(event);
});
offError = self.once('error', function (event) {
offDone();
offStdout();
reject(event);
});
offStdout = self.on('stdout', function (event) {
if (typeof notify === 'function') {
notify.call(self, event);
}
});
worker.postMessage({
'type': 'file',
'data': new Uint8Array(arrayBuffer)
});
worker.postMessage({
'type': 'command',
'command': 'go'
});
});
done.catch(noop).then(function () {
worker.terminate();
});
return done;
});
});
promise.catch(noop).then(function () {
if (promise === self.execPromise) {
delete self.execPromise;
}
});
return promise;
};
pngcrush.prototype.initWorker = function () {
var self = this;
if (this.workerPromise) {
return this.workerPromise;
}
var promise = this.workerPromise = new Promise(function (resolve, reject) {
var worker = new Worker('worker.js');
worker.onerror = function (event) {
var callbacks = [];
reject(event);
Array.prototype.push.apply(callbacks, self.callbacks.error);
while (callbacks.length) {
callbacks.shift().call(self, event);
}
};
worker.onmessage = function (event) {
if (event.data.type === 'ready') {
worker.onmessage = function (event) {
var name = event.data.type;
if (typeof self.callbacks[name] !== 'undefined') {
var callbacks = [];
Array.prototype.push.apply(callbacks, self.callbacks[name]);
while (callbacks.length) {
callbacks.shift().call(self, event);
}
}
};
resolve(worker);
}
};
});
promise.catch(noop).then(function () {
if (promise === self.workerPromise) {
delete self.workerPromise;
}
});
return promise;
};
pngcrush.prototype.on = function (name, callback) {
var self = this;
if (typeof this.callbacks[name] !== 'undefined' && typeof callback === 'function') {
this.callbacks[name].push(callback);
var off = (function () {
var ran = false;
return function () {
if (ran === true) {
return;
}
ran = true;
var idx = self.callbacks[name].lastIndexOf(callback);
if (idx !== -1) {
self.callbacks[name].splice(idx - 1, 1);
}
};
})();
return off;
}
return noop;
};
pngcrush.prototype.once = function (name, callback) {
var off = this.on(name, function () {
off();
callback.apply(this, arguments);
});
return off;
};
pngcrush.prototype.readAsArrayBuffer = function (file) {
var fileReader = new FileReader();
return new Promise(function (resolve, reject) {
fileReader.onerror = reject;
fileReader.onload = resolve;
fileReader.readAsArrayBuffer(file);
});
};
pngcrush.prototype.readAsDataURL = function (file) {
var fileReader = new FileReader();
return new Promise(function (resolve, reject) {
fileReader.onerror = reject;
fileReader.onload = resolve;
fileReader.readAsDataURL(file);
});
};
exports.pngcrush = pngcrush;
})(this);

javascript promise schedule multiple function

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>

Categories