Javascript EventLoop
console.log('1 ' + new Date());
setTimeout(function() {
console.log('2 ' + new Date());
}, 1000)
console.log('3 ' + new Date());
1 Fri Jun 05 2015 17:29:25 GMT+0200 (CEST)
3 Fri Jun 05 2015 17:29:25 GMT+0200 (CEST)
2 Fri Jun 05 2015 17:29:26 GMT+0200 (CEST)
var sleep = function(seconds) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8080/sleep.php?seconds=" + seconds, false);
xhr.send(null);
};
<?php
//sleep.php
sleep($_GET['seconds']);
console.log(new Date());
sleep(2);
console.log(new Date());
Fri Jun 05 2015 17:24:19 GMT+0200 (CEST)
Fri Jun 05 2015 17:24:21 GMT+0200 (CEST)
console.log('1 ' + new Date());
setTimeout(function() {
console.log('2 ' + new Date());
}, 1000)
sleep(2);
console.log('3 ' + new Date());
1 Fri Jun 05 2015 17:29:25 GMT+0200 (CEST)
3 Fri Jun 05 2015 17:29:27 GMT+0200 (CEST)
2 Fri Jun 05 2015 17:29:27 GMT+0200 (CEST)
console.log('1 ' + new Date());
setTimeout(function() {
console.log('2 ' + new Date());
}, 1000)
setTimeout(function() {
console.log('3 ' + new Date());
}, 500)
sleep(2);
1 Fri Jun 05 2015 17:30:34 GMT+0200 (CEST)
3 Fri Jun 05 2015 17:30:37 GMT+0200 (CEST)
2 Fri Jun 05 2015 17:30:37 GMT+0200 (CEST)
console.log('1 ' + new Date());
setTimeout(function() {
console.log('2a ' + new Date());
sleep(1)
console.log('2b ' + new Date());
}, 0);
setTimeout(function() {
console.log('3a ' + new Date());
sleep(1)
console.log('3b ' + new Date());
}, 0);
1 Fri Jun 05 2015 17:42:47 GMT+0200 (CEST)
2a Fri Jun 05 2015 17:42:49 GMT+0200 (CEST)
2b Fri Jun 05 2015 17:42:50 GMT+0200 (CEST)
3a Fri Jun 05 2015 17:42:50 GMT+0200 (CEST)
3b Fri Jun 05 2015 17:42:51 GMT+0200 (CEST)
setTimeout(function() {});
setInterval(function() {});
document.getElementById('foo').addEventListener('click', function() {});
var i = new Image();
i.onload = function() {});
$('.class').on('click', function() {});
xhr.open("GET", "/foo/bar", true);
xhr.onload = function (e) {};
xhr.onerror = function (e) {};
Limitations
var i1 = new Image();
var i2 = new Image();
var loadingCount = 2;
function oneLoaded(img)
{
console.log('One image is loaded');
if (--loadingCount === 0) {
allLoaded();
}
}
function allLoaded()
{
console.log('All images are loaded');
}
i1.onload = oneLoaded;
i2.onload = oneLoaded;
function imageSize(url)
{
var i = new Image();
i.src = url;
return [i.width, i.height];
}
function imageSize(url)
{
var i = new Image();
i.src = url;
i.onload(function() {
???
});
return ???
}
function imageSize(url, callback)
{
var i = new Image();
i.src = url;
i.onload(
callback([i.width, i.height]);
});
}
Promises
- ES6
- Q
- AngularJs
var promise = new Promise(function(resolve, reject) {
// ...
if (itWorks) {
resolve(myData);
}
else {
reject(Error("Oh snap"));
}
});
promise.then(function(result) {
console.log(result);
}, function(err) {
console.log(err);
});
How it works?
function callMeMayBe()
{
return new Promise(function(resolve, reject) {
var delay = 2000 * Math.random();
setTimeout(function() {
var success = Math.random() < 0.5;
if (success) {
resolve();
} else {
reject();
}
}, delay);
});
}
callMeMayBe().then(function(result) {
console.log('Hello');
});
Sample
function oneLoaded()
{
console.log('One image is loaded');
}
function allLoaded()
{
console.log('All images are loaded');
}
var i1 = new ImageWithPromise();
var i2 = new ImageWithPromise();
i1.$promise.then(oneLoaded);
i2.$promise.then(oneLoaded);
Promise.all([i1.$promise, i1.$promise]).then(allLoaded);
Promises
function imageSize(url)
{
var i = new Image();
i.src = url;
return new Promise(function(resolve, reject) {
i.onload(function() {
resolve([i.width, i.height]);
});
i.onerror(function() {
reject('Oh snap!');
});
}
}
Promises
imageSize(url).then(function(size) {
console.log(size);
}).catch(function(err) {
console.log(err);
});
$httpProvider.interceptors.push(function ($q, $injector) {
return {
responseError: function (response) {
if (response.status === 401) {
return $injector.get('authPrompt').retryHttp(response.config);
}
return $q.reject(response);
}
};
});
Advanced usage
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
authPrompt
.factory('authPrompt', function ($auth, $mdDialog, $q, $http) {
var prompting = null;
return {
retryHttp: function (request) {
var deffered = $q.defer();
this.login().then(function () {
$http(request).then(function (data) {
deffered.resolve(data);
}, function (reason) {
deffered.reject(reason);
});
}, function (reason) {
deffered.reject(reason);
});
return deffered.promise;
},
login: ...
});
authPrompt
.factory('authPrompt', function ($auth, $mdDialog, $q, $http) {
var prompting = null;
return {
retryHttp: ...
login: function () {
if (null !== prompting) {
return prompting;
}
prompting = $mdDialog.show({
controller: function ($scope) {
$scope.authenticate = function (provider) {
$auth.authenticate(provider).then(function () {
$mdDialog.hide();
});
};
$scope.cancel = $mdDialog.cancel;
},
templateUrl: 'templates/auth/popin/login.tpl.html'
})['finally'](function () {
prompting = null;
});
return prompting;
}
};
});
Question ?
Javascript EventLoop
By Jérémy DERUSSÉ
Javascript EventLoop
- 1,428