Sometimes you need to do things in order. Do one thing, wait for it to finish, maybe asynchronous, and the continue with the next one. This in programming is called a tail implementation. Here is a very basic tail in javascript.
var data = [16, 11, 9, 7, 26, 25],
len = data.length,
tail = [],
start = null,
i;
// simulate lots of data
for (i = 0; i < len; i++) {
go({pos:i, val:data[i]});
}
/**
* Entry point - incomming data!
*/
function go(obj) {
// add data to tail array
tail.push(obj);
// start first run, on first data entry
if (!start) {
run(tail.shift(), finish);
// start the loop
start = true;
}
}
/**
* Run command from tail array
*/
function run(obj, cb) {
var delay = getRandomInt(1000, 5000);
// simulates job, with different time execution
setTimeout(function() {
console.log("CMD: " + obj.pos + ":" + obj.val);
cb({isok:"OK", delay:delay});
}, delay);
}
/**
* Callback from run(). Hare we contionue the
* execution if tail array contains other commands.
*/
function finish(res) {
console.log("RES: isok:" + res.isok + " delay:" + res.delay);
console.log("INF: tail length:" + tail.length);
console.log("==========");
// if no data in array, stop execution
if (tail.length === 0) {
// stop the loop
start = null;
return;
// if still data continue execution with next tail element
} else {
run(tail.shift(), finish);
}
}
/**
* Randomly generated delay
*/
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Create a new object, that prototypally inherits from the Error constructor
function MyError(message) {
this.name = 'MyError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
try {
throw new MyError();
} catch (e) {
console.log(e.name); // 'MyError'
console.log(e.message); // 'Default Message'
}
try {
throw new MyError('custom message');
} catch (e) {
console.log(e.name); // 'MyError'
console.log(e.message); // 'custom message'
}
... checks:
isJson(str)isStr(str)isArr(arr)isObj(obj)isNum(num)isUndefined()isFnx(fx)isSet(variable)... converters:
toBool(data)... seekers:
inArr(needle, arrhaystack)inStr(str, char)getKey(obj, value)setCharAt(str, index, char)// ...checks
function isJson(str) {
try {
return JSON.parse(str);
} catch (e) {
return false;
}
}
function isStr(str) {
try {
return str.constructor === String;
} catch (e) {
return false;
}
}
function isArr(arr) {
try {
return arr.constructor === Array;
} catch (e) {
return false;
}
}
function isObj(obj) {
try {
return obj.constructor === Object;
} catch (e) {
return false;
}
}
function isNum(num) {
return !isNaN(num);
}
function isUndefined(data) {
return typeof data === "undefined";
}
function isFnx(fx) {
return typeof fx === 'function';
}
function isSet() {
var a = arguments,
l = a.length,
i = 0,
undef;
if (l === 0) {
throw new Error('Empty isset');
}
while (i !== l) {
if (a[i] === undef || a[i] === null) {
return false;
}
i++;
}
return true;
}
// ...converters
function toBool(data) {
return !!data;
}
/// ...seekers
function inArr(needle, arrhaystack) {
return (arrhaystack.indexOf(needle) > -1);
}
function inStr(str, char) {
if (typeof str === 'string') {
return str.indexOf(char) !== -1;
}
return false;
}
function getKey(obj, value){
for(var key in obj) {
if(obj[key] == value){
return key;
}
}
return null;
}
function setCharAt(str, index, char) {
return str.substr(0, index) + char + str.substr(index + char.length);
};
Universal operating system installer.
For people short on SD cards: Berryboot is a simple boot selection screen, allowing you to put multiple Linux distribution on a single SD card.
In addition it allows you to put the operating system files on an external USB hard drive instead of on the SD card itself.
Scan
iwlist wlan0 scan
Connect
iwconfig wlan0 essid "<ssid>" key "<pass>"