Well I don't know if mySQL.query()
function returns a Promise object or not. Assuming that it doesn't, lets try to simulate our mySQL
database which includes a query
method which would return a result asynchronously within 200ms.
mySQL = { '1234567890' : {name: "John Doe", age: 22},
'646494964' : {name: "Mary Jones", age: 28},
'4498549646' : {name: "Sam Johnson", age: 44},
'46654654664': {name: "Terry Gibson", age: 18},
'546646546' : {name: "Patricia Snow", age: 31},
query : function(q,cb){
setTimeout(function(db){
var result = db[q];
!!result ? cb(false,result)
: cb("Nothing found for query #: " + q, void 0);
}, Math.random()*200, this);
}
}
Now the following snippet will promisify any asynchronous call which takes a data and an error first type callback (cb(err, res)
).
function promisify(fun){
return function(data){
return new Promise((v,x) => fun(data, (err,data) => !!err ? x(err)
: v(data)));
}
}
Once we promisify mySQL.query
like promisfy(mySQL.query.bind(mySQL))
it will start returning promises. (We use bind
here since when the fun
argument variable of the promisify
function gets assigned to mySQL.query
, it will invoke mySQL.query
with the this
as promisify
's scope and we don't want that. So we secure fun
to be bound to mySQL
all the time. (Bonus JS knowledge here..!)
Well OK we are almost ready, let's wrap it yup and "sequentially" query our matchstick DB which supports promises. In order to sequentially tie a series of promise-returning-queries in an array, it's best to use a .reduce()
to chain up the .then()
stages of the previous query to the next. Cool..!
function promisify(fun){
return function(...data){
return new Promise((v,x) => fun(...data, (err,data) => !!err ? x(err) : v(data)));
};
}
function mysqlQuery(query,cb){
setTimeout(function(){
var result = database[query];
!!result ? cb(false,result) : cb("Nothing found for query #: " + query, void 0);
}, Math.random()*200);
}
var numbers = ['1234567890', '646494964', '122', '4498549646', '46654654664', '546646546'],
mySQL = { '1234567890' : {name: "John Doe", age: 22},
'646494964' : {name: "Mary Jones", age: 28},
'4498549646' : {name: "Sam Johnson", age: 44},
'46654654664': {name: "Terry Gibson", age: 18},
'546646546' : {name: "Patricia Snow", age: 31},
query : function(q,cb){
setTimeout(function(db){
var result = db[q];
!!result ? cb(false,result)
: cb("Nothing found for query #: " + q, void 0);
}, Math.random()*200, this);
}
},
contents = [];
numbers.reduce((p,n) => p.then(c => promisify(mySQL.query.bind(mySQL))(n))
.then(d => contents.push(d), e => console.log(e)), Promise.resolve())
.then(_ => console.log(contents));
.as-console-wrapper { max-height: 100% !important; top: 0; }