Amazon Interview Question
Web DevelopersTeam: AWS
Country: United States
Interview Type: Phone Interview
I wrote this implementation according to the original Promises/A spec (with the .then method instead of .addCallback and .addFailCallback)
//THE PROMISE OBJECT (consumer)
function Promise(){
}
Promise.prototype.then = function(onFulfill, onReject){
var defer = new Deferred();
this.onFulfill = function(val){
var returnVal = onFulfill.call(this, val);
defer.resolve(returnVal);
};
this.onReject = function(){
onReject.call(this);
defer.reject();
};
return defer.promise();
}
//THE DEFERRED OBJECT (producer)
function Deferred(){
this.promiseObj = new Promise();
}
Deferred.prototype.promise = function(){
return this.promiseObj;
}
Deferred.prototype.resolve = function(value){
this.promiseObj.value = value;
if(typeof this.promiseObj.onFulfill === 'function')
this.promiseObj.onFulfill.call(this.promiseObj, value);
}
Deferred.prototype.reject = function(){
if(typeof this.promiseObj.onReject === 'function')
this.promiseObj.onReject.call(this.promiseObj);
}
//EXAMPLE CALLBACKS
function printAndDouble(res){
console.log(res);
return res * 2;
}
function printError(){
console.log('Error!');
}
function printFinal(res){
console.log('Final value is: ' + res);
}
//EXAMPLE ASYNC WORK
function myAsyncThingy() {
var def = new Deferred(); // Create a deferred to use for managing our async behavior
setTimeout(function () { def.resolve(20) }, 1000); // In one second call the resolve function to mark it as success
return def.promise(); // return the promise for our deferred to the client
}
//EXAMPLE CALL
myAsyncThingy().then(printAndDouble, printError).then(printFinal);
I have a basic implementation for the requirements mentioned in the question. It should not be compared with the actual deferred and promise implementation.
function deferred() {
console.log("Deferred Created");
var state = "pending";
var successful;
var failure;
function promiseFunc(){
this.addCallBack = function(success){
console.log("addCallBack Called :" + success);
successful = success;
}
this.addFailCallBack = function(fail){
console.log("addFailCallBack Called :" + fail);
failure = fail;
}
}
var promise = new promiseFunc();
this.resolve = function (){
if(state == "pending"){
state = "resolved";
console.log("Deferred is resolved");
if(typeof(successful) == 'function' ){
successful();
} else {
console.log(successful);
}
} else {
return console.log("Already " + state + " : Cannot be resolved now");
}
}
this.reject = function (){
if (state == "pending"){
state = "rejected";
console.log("Deferred is rejected");
if(typeof(failure) == 'function' ){
failure();
} else {
console.log(failure);
}
} else {
return console.log("Already " + state + " : Cannot be rejected now");
}
}
this.getPromise = function (){
return promise;
}
}
function myAsyncThing(){
var def = new deferred();
setTimeout(function (){def.resolve()},1000);
return def.getPromise();
}
var promise = myAsyncThing();
promise.addCallBack(function(){
console.log("We did it");
});
promise.addFailCallBack(function(){
console.log("We failed");
});
You can checkout my jsfiddle jsfiddle.net /AbhikMitra /5192aqm7 /14/
var deferredLib =(function(){
function Deferred(){
this.successFn = [],this.failureFn =[];
this.promise = new Promise(this.successFn,this.failureFn);
}
Deferred.prototype = (function(){
function resolve (success){
this.successFn.forEach(function(fn){
fn(success);
});
}
function reject(error){
this.failureFn.forEach(function(fn){
fn(error);
});
}
return {
resolve:resolve,
reject:reject
}
})();
function Promise(successFn,failureFn){
this.successFn = successFn;
this.failureFn = failureFn;
}
Promise.prototype = (function(){
function then(success,failure){
var deferred = new Deferred();
this.successFn.push(function(data){
deferred.resolve(success(data));
});
this.failureFn.push(function(data){
deferred.reject(failure(data));
});
return deferred.promise;
}
return {
then:then
}
})();
function defer(){
return new Deferred();
}
return {
defer:defer
}
})();
function test(){
var promise = deferredFn();
promise.then(success,error).then(function(){
console.log("I ahve been chained");
},function(){
console.log("Chained error");
})
promise.then(function(success){
console.log(success);
},error);
}
function success(){
console.log("I am successful");
}
function error(){
console.log("I am error");
}
function deferredFn(){
var deferred = deferredLib.defer();
console.log("Deferred sent");
setTimeout(function(){
deferred.reject("I am a deferred");
},2000)
return deferred.promise;
}
test();
I bombed this because I was unsure of the syntax for creating objects with JavaScript. But here's what I ended up with.
- Kevin.Pheasey April 10, 2013