Reputation: 932
I'm trying to learn using deferred and I'm stumbled as I'm not getting expected arguments in the "then" block.
var makeCall = function (err, param) {
var deferred = Q.defer();
setTimeout(function() {
console.log(1111, err, param);
deferred.resolve(err, param);
}, 1000);
return deferred.promise;
};
makeCall('test', '11').then(function(err, data) {
console.log(222, err, data);
});
Console. with 1111 outputs correct data that was returned from an Ajax call but 222 does not.
Upvotes: 4
Views: 9128
Reputation: 1
Note, a) Not certain if interpret Question correctly; b) Promise
appear not implemented universally same in every browser, nor at jsfiddle. This may be helpful JavaScript Promises http://www.html5rocks.com/en/tutorials/es6/promises/ (where below piece can be tried at console
; should also work at mozilla nightly console
, which appear to implement Promise
object)
Try this (pattern)
var makeCall = function(err, param) {
return new Promise(function(resolve, reject ) {
setTimeout(function() {
console.log(1111, err, param);
return (err && param) ?
resolve(err, param) :
reject(Error("error"))
})
}, 1000);
};
makeCall("test", "11")
.then(function(result) {
console.log(222, result);
makeCall("test2","11");
makeCall("abc", 123) // `chain` test
},
function(err) {
console.log(err)
});
Upvotes: 1
Reputation: 276306
In your case, I'd avoid the deferred altogether.
var makeCall = function(err,param){
if(err) return Q.reject(err);
return Q(param).delay(1000);
};
(fiddle)
The usage is similar to thefoureye's answer from earlier, since promises are like synchronous code, you interact with them using return values and catch statements. Nodebacks ((err,data)
) and callbacks more generally remove many desirable properties from asynchronous code, and promises aim to restore those properties.
makeCall(new Error("Hello"),"SomeValue").then(function(cata){
console.log("Got correct data!",data);
}).catch(function(err){
console.log("Got error :(",err); // this would happen since we passed an error.
});
I also assume that that this function is imaginary, and not representative of a real API.
You mainly use deferred objects when converting an API to promises, which you don't need to in this case.
Upvotes: 2
Reputation: 239473
deferred.resolve
can accept only one argument and that is to mark the success of the asynchronous call. To notify of the failure, you need to use deferred.reject
. So your code has to be changed like this
var makeCall = function(err,param){
setTimeout(function () {
console.log(1111, err, param);
var deferred = Q.defer();
if (err) {
deferred.reject(err);
} else {
deferred.resolve(param);
}
}, 1000);
return deferred.promise;
};
makeCall(undefined, '11').then(function (data) {
console.log(222, data);
}, function (err) {
console.log(333, err);
});
This will print 222 '11'
, to simulate the failure case, just invoke makeCall
with any Truthy value as the first argument, for example
makeCall('11')....
it will invoke the failure handler, and the output will be 333 '11'
.
Upvotes: 5