Issue with Native promise resolve outside the function - javascript

I am trying to refactor jQuery promises with native promise for the below codes.
public functionA(){
const dArray = Array<JQueryDeferred<{a:string}>>=[];
//other lines of logic
functionB(dArray, /*other parameters*/);
}
private functionB(dArray : Array<JQueryDeferred<{a:string}>>[], /*other arguments*/){
//other lines of logic
for(var i=0;i<10;i++){
dArray.push($.Deferred());
var ele = dArray.length-1;
functionC(dArray[ele], /*other parameters*/)
.done((result: { a:string}) => {
// logic
})
.always() => {
// some additional logic
});
}
}
private functionC(d: JQueryDeferred<{a:string}>):JQueryDeferred<{a:string}>{
if(){//some condition
// some other logic
d.resolve({ a: "completed" });
}
return d;
}
As the above methods involved passing deferred objects to multiple functions and array of deferred objects, just seeking help of any better method to rewrite the above with native promise like below;
public functionA(){
const pArray = Array<Promise<{a:string}>>=[];
//other lines of logic
functionB(pArray, /*other parameters*/);
}
private functionB(pArray : Array<Promise<{a:string}>>[], /*other arguments*/){
//other lines of logic
for(var i=0;i<10;i++){
pArray.push((new Promise<{ a:string; }>(resolve => resolvePromise = resolve)););
var ele = pArray.length-1;
functionC(pArray[ele], /*other parameters*/)
.then((result: { a:string }) => {
// logic
})
.finally() => {
// some additional logic
});
}
}
private functionC(p: Promise<{a:string}>):Promise<{a:string}>{
if(){//some condition
// some other logic
// i am stuck here..
p.resolve({ a: "completed"}) //no such resolve method to call
// tried with Promise.resolve({ a: "completed"}),
// but my question - will it resolve same way as the index based
// resolve like the jQuery deferred version?
}
return p;
}
Thanks in advance.

Promises are not callbacks that you pass into a function. Promises are result values that you return from a function. They are constructed inside the function, and resolved by the logic inside the function only. Unlike a Deferred, they cannot be resolved by anyone who gets a hand on them.
From this approach, the correct code follows:
public functionA() {
// other lines of logic
const pArray = functionB(/* other arguments */);
}
private functionB(/* other parameters */): Array<Promise<{a:string}>> {
//other lines of logic
const promises: Array<Promise<{a:string}>> = [];
for (var i=0; i<10; i++) {
promises.push(
functionC(/* … */).then((result: { a:string }) => {
// logic
}).finally() => {
// some additional logic
})
);
}
return promises;
// ^^^^^^^^^^^^^^^
}
private functionC(): Promise<{a:string}> {
return new Promise<{ a:string; }>((resolve, reject) => {
// ^^^^^^^^^^^^^^^^^^
if (/* some condition */) {
// some other logic
resolve({ a: "completed"});
} else {
reject(new Error());
}
});
}

Related

How to write polyfill of promise which works for Promise.resolve()?

I'm trying to write a promise polyfill to get a better understanding of promise.
I've searched the internet and found a code which I'm able to understand to some extent.
function CustomPromise(executor) {
var state=PENDING;
var value = null;
var handlers=[];
var catchers = [];
function resolve(result) {
if(state!==PENDING) return;
state=FULFILLED;
value = result;
handlers.forEach((h)=>h(value)); //this line
}
function reject(error) {
if(state!==PENDING)return;
state=REJECTED;
value=error;
catchers.forEach(c=>c(value)); // this line
}
this.then = function(successCallback) {
if(state === FULFILLED) {
successCallback(value);
}else {
handlers.push(successCallback);
}
return this;
}
this.catch = function(failureCallback) {
if(state===REJECTED){
failureCallback(value)
} else {
catchers.push(value);
}
}
executor(resolve,reject);
}
Even in this I'm unable to understand the use of handlers and catchers. It was said that they are for situation when promise is not fulfilled or rejected. Explaining these two lines will also help.
Now, the actual issue with above implementation is it doesn't work for when used like let p1 = Promise.resolve("Hello World");. I have tried converting it to class based but I'm unable to do that.
My attempt:
class CustomPromise {
constructor(callback){
this.state = PENDING;
this.executor = callback;
this.value = null;
this.handlers = [];
this.catchers = [];
this.then = function(successCallback) {
if(this.state === FULFILLED) {
successCallback(this.value);
}else {
this.handlers.push(successCallback);
}
return this;
};
this.catch = function(failureCallback) {
if(this.state===REJECTED){
failureCallback(this.value)
} else {
this.catchers.push(this.value);
}
};
}
static resolve(result) {
if(this.state!==PENDING) return;
this.state=FULFILLED;
this.value = result;
this.handlers.forEach((h)=>h(this.value));
// return new CustomPromise( function ( fulfil ) {
// fulfil( value );
// });
}
static reject(error) {
if(this.state!==PENDING)return;
this.state=REJECTED;
this.value=error;
this.catchers.forEach(c=>c(this.value));
}
// executor(resolve,reject);
}
Can someone correct the functional approach so that it works for CustomPromise.resolve() scenario or correction in my class based approach will also be appreciated.
EDIT: Tried CustomPromise.prototype.resolve = function(error) {...}
still getting same error CustomPromise.resolve is not a function
EDIT2 : In class based approach I'm unable to implement executor callback. I just want either one of the approach to work for case like Promise.resolve()
To extend the first (working) version of CustomPromise, add the code you seem to have been trying with in commented-out code in the (non-working) class-version you had. But it had two little problems. Still, the idea to use new CustomPromise is the right one:
CustomPromise.resolve = value => new CustomPromise(fulfil => fulfil(value));
CustomPromise.reject = error => new CustomPromise((_, reject) => reject(error));
So if you add that below your CustomPromise function definition, it'll work:
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function CustomPromise(executor) {
var state=PENDING;
var value = null;
var handlers=[];
var catchers = [];
function resolve(result) {
if(state!==PENDING) return;
state=FULFILLED;
value = result;
handlers.forEach((h)=>h(value));
}
function reject(error) {
if(state!==PENDING)return;
state=REJECTED;
value=error;
catchers.forEach(c=>c(value));
}
this.then = function(successCallback) {
if(state === FULFILLED) {
successCallback(value);
}else {
handlers.push(successCallback);
}
return this;
}
this.catch = function(failureCallback) {
if(state===REJECTED){
failureCallback(value)
} else {
catchers.push(value);
}
}
executor(resolve,reject);
}
// Added:
CustomPromise.resolve = value => new CustomPromise(fulfil => fulfil(value));
CustomPromise.reject = error => new CustomPromise((_, reject) => reject(error));
// Demo
let p = CustomPromise.resolve(42);
let q = CustomPromise.reject("custom error");
p.then(value => console.log("p", value));
q.catch(error => console.log("q", error));
Disclaimer: this polyfill is not compliant with the Promises/A+ specification let be it would be compliant with the ECMAScript specification for Promise.
Some of the problems it has:
It allows the then callback to be executed synchronously. The then callback should never be executed synchronously, but always be called via a queued job (i.e. asynchronously).
The catch method wrongly returns undefined. It should return a promise.
The then method wrongly returns the same promise as it is called on. It should return a different promise, that resolves with the value that will be returned by the callback.
The then method ignores a second argument. It should take a second function which should serve as a rejection callback (like catch).
When the promise is resolved with a thenable, the thenable is wrongly used as fulfillment value. This is not how it is supposed to work. A very important aspect of promises, is that promises chain, i.e. when a promise resolves to another promise (or thenable), it gets "locked in" to that second promise, so that it will follow the way that second promise resolves.
There are many correct implementations to be found. I posted my own Promises/A+ compliant implementation in this answer. It does not have the resolve and reject static methods, but it would require the same additional code as given above.

Loop until all events are received in javascript

I have a function that waits for four external events (I have no control on them. They are randomly received)
function Foo() {
var this.data_1;
var this.data_2;
var this.data_3;
var this.data_4;
}
Foo.prototype.getData = function(){
deviceOne.on('data', (data) => {
this.data_1 = data;
});
deviceTwo.on('data', (data) => {
this.data_2 = data;
});
deviceThree.on('data', (data) => {
this.data_3 = data;
});
deviceFour.on('data', (data) => {
this.data_4 = data;
});
return {
"data_from_device_1": this.data_1,
"data_from_device_2": this.data_2,
"data_from_device_3": this.data_3,
"data_from_device_4": this.data_4
}
};
var foo = new Foo();
console.log(foo.getData()); // {'undefined', 'undefined', 'undefined', 'undefined'}
As you can see, the function won't wait for them and it will return 4 undefined objects. I've been looking for a solution and it seems like using async could help. It's just I didn't understand how to use it correctly in my case
To use async (and it does help here), first you need to do a promise version of your deviceXYZ.on:
const waitForData = device => new Promise((resolve, reject) => {
device.on('data', (data) => {
resolve(data);
});
// ...presumably hook up some kind of error event and use `reject` here...
});
Then (I've converted to class syntax here since if you're using async, you can use the new, simpler notation):
class Foo {
async getData() {
// ^^^^^
const data = await Promise.all([
// ^^^^^
waitForData(deviceOne),
waitForData(deviceTwo),
waitForData(deviceThree),
waitForData(deviceFour)
]);
this.data_1 = data[0];
this.data_2 = data[1];
this.data_3 = data[2];
this.data_4 = data[3];
return {
data_from_device_1: this.data_1,
data_from_device_2: this.data_2,
data_from_device_3: this.data_3,
data_from_device_4: this.data_4
};
}
}
Then code using it also has to be in an async function:
( async () => {
// ^^^^^
try {
const foo = new Foo();
console.log(await foo.getData()); // {'undefined', 'undefined', 'undefined', 'undefined'}
// ---------^
} catch (e) {
// Handle/report error
}
})();
...or it can use the promise directly in a non-async function:
const foo = new Foo();
foo.getData()
.then(result => {
console.log(result);
})
.catch(error => {
// Handle/report error
});
More:
async/await
Promise
Promise.all
class
Arrow functions
Side note: This is invalid syntax:
function Foo() {
var this.data_1; // Error here
var this.data_2;
var this.data_3;
var this.data_4;
}
At the moment, you don't declare properties in JavaScript. However, before too long (possibly ES2019, almost certainly ES2020) class syntax will be extended by the class fields proposal, currently at Stage 3 in the proposals process. When that happens, you can declare the "shape" of objects created by the Foo class (which can mean the objects go through fewer shape changes, which helps improve performance; it's also useful documentation for people reading the code). That would change Foo to look like this:
class Foo {
data_1; // These are field (property) declarations
data_2;
data_3;
data_4;
async getData() {
// ...
}
}

Use Promises Correctly in Synchronous Project

I have a standard JavaScript project. It is mostly synchronous with a few callbacks. I needed to use a 3rd party library to simplify things. The issue is that this library is based on an async approach and Promises. I have never really used this approach before.
I have a situation where I just need something = get_info(); The code is all very modular, so there are multiple function calls stacked up. The problem is this get_info is async. I just can't figure out how to use this async function withing my project without having to rewrite the whole thing.
Edit: Here is an example of similar code
function my_class() {
this.do_something( data ) {
if ( this.get_data() == data ) {
do_the_thing();
}
}
this.get_data = function() {
return library.get_info( arguments ); //can't do this, returns a promise
}
}
var stuff = new my_class();
for ( var i = 0; i < len; i++ ) {
stuff.do_something( i )
}
Again, the goal is to not rewrite this entire part of the application. Thoughts?
There is no need to promisify every function that gets called in the chain. You can call either synchronous or asynchronous functions as much as you want within the chain of the promises. All you have to think about is where to wait for the resolved value.
Your code isn't far off from working, a simple addition of a .then() block makes it work.
Working example below:
function my_class() {
this.do_something(data) {
//Call the promise-returning function
this.get_data()
.then((resolvedData) => {
//Wait for promise resolution
//and compare the resolved value to 'data'
if (resolvedData === data) {
do_the_thing();
}
})
.catch();
}
this.get_data = () => {
return library.get_info(arguments);
}
}
var stuff = new my_class();
for (var i = 0; i < len; i++) {
stuff.do_something(i)
}
How does it work?
do_something(i) is called
this.get_data() is called from inside the do_something() function.
When the promise that get_data() returns has been resolved, execution continues into then .then() block.
The resolvedData is the resolved value from the get_data() promise.
Compare the values, and continue.
As you can see, this does not take into consideration that the for-loop will continue even though the call to stuff.do_something(i) hasn't completed.
It is unclear in your question if you allow them all to run in parallel (like now) or if you need that they run in sequence.
If you want to to know if all calls are done, you can let do_something() return a promise and then wait for them all to resolve using Promise.all(), like below
function my_class() {
this.do_something(data) {
//Call the promise-returning function
//Note that we return the same promise - no need to create a new one!
return this.get_data()
.then((resolvedData) => {
//Wait for promise resolution
//and compare the resolved value to 'data'
if (resolvedData === data) {
do_the_thing();
}
})
.catch();
}
this.get_data = () => {
return library.get_info(arguments);
}
}
var stuff = new my_class();
//
var promises = [];
for (var i = 0; i < len; i++) {
//Push each promise to the array
promises.push(stuff.do_something(i));
}
Promise.all(promises)
.then(() => {
console.log("All promises have been resolved!")
})
.catch(() => {
//Handle errors
});
function my_class() {
this.do_something( data ) {
return new Promise(function(resolve,reject){
this.get_data().then(function(dataReceiced){
//reading promise retuned by get_data();
if(data == dataReceiced){
do_the_thing(); //need to promisify this also to use then();
resolve('Done');
} else { reject('Error'); }
});
});
}
}
this.get_data = function() {
return library.get_info( arguments ); //can't do this, returns a promise
}
}
i=0; // keep i global
var stuff = new my_class();
function doStuff(){
if(i < len){ mainStuff(); }
}
function mainStuff(){
stuff.do_something( i ).then(function(){
i++;
doStuff();
});
};
doStuff(); // to start process.
You need to promisify every function involved in the chain ..
Something like this..
Not sure about the complete scenario , code will look something like this.

What are the idiomatic ways to implement serial "for" and "while" loops with native ES6 promises? [duplicate]

How to correctly construct a loop to make sure the following promise call and the chained logger.log(res) runs synchronously through iteration? (bluebird)
db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise
I tried the following way (method from http://blog.victorquinn.com/javascript-promise-while-loop )
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
});
Although it seems to work, but I don't think it guarantees the order of calling logger.log(res);
Any suggestions?
If you really want a general promiseWhen() function for this and other purposes, then by all means do so, using Bergi's simplifications. However, because of the way promises work, passing callbacks in this way is generally unnecessary and forces you to jump through complex little hoops.
As far as I can tell you're trying :
to asynchronously fetch a series of user details for a collection of email addresses (at least, that's the only scenario that makes sense).
to do so by building a .then() chain via recursion.
to maintain the original order when handling the returned results.
Defined thus, the problem is actually the one discussed under "The Collection Kerfuffle" in Promise Anti-patterns, which offers two simple solutions :
parallel asynchronous calls using Array.prototype.map()
serial asynchronous calls using Array.prototype.reduce().
The parallel approach will (straightforwardly) give the issue that you are trying to avoid - that the order of the responses is uncertain. The serial approach will build the required .then() chain - flat - no recursion.
function fetchUserDetails(arr) {
return arr.reduce(function(promise, email) {
return promise.then(function() {
return db.getUser(email).done(function(res) {
logger.log(res);
});
});
}, Promise.resolve());
}
Call as follows :
//Compose here, by whatever means, an array of email addresses.
var arrayOfEmailAddys = [...];
fetchUserDetails(arrayOfEmailAddys).then(function() {
console.log('all done');
});
As you can see, there's no need for the ugly outer var count or it's associated condition function. The limit (of 10 in the question) is determined entirely by the length of the array arrayOfEmailAddys.
I don't think it guarantees the order of calling logger.log(res);
Actually, it does. That statement is executed before the resolve call.
Any suggestions?
Lots. The most important is your use of the create-promise-manually antipattern - just do only
promiseWhile(…, function() {
return db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
});
})…
Second, that while function could be simplified a lot:
var promiseWhile = Promise.method(function(condition, action) {
if (!condition()) return;
return action().then(promiseWhile.bind(null, condition, action));
});
Third, I would not use a while loop (with a closure variable) but a for loop:
var promiseFor = Promise.method(function(condition, action, value) {
if (!condition(value)) return value;
return action(value).then(promiseFor.bind(null, condition, action));
});
promiseFor(function(count) {
return count < 10;
}, function(count) {
return db.getUser(email)
.then(function(res) {
logger.log(res);
return ++count;
});
}, 0).then(console.log.bind(console, 'all done'));
Here's how I do it with the standard Promise object.
// Given async function sayHi
function sayHi() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Hi');
resolve();
}, 3000);
});
}
// And an array of async functions to loop through
const asyncArray = [sayHi, sayHi, sayHi];
// We create the start of a promise chain
let chain = Promise.resolve();
// And append each function in the array to the promise chain
for (const func of asyncArray) {
chain = chain.then(func);
}
// Output:
// Hi
// Hi (After 3 seconds)
// Hi (After 3 more seconds)
Given
asyncFn function
array of items
Required
promise chaining .then()'s in series (in order)
native es6
Solution
let asyncFn = (item) => {
return new Promise((resolve, reject) => {
setTimeout( () => {console.log(item); resolve(true)}, 1000 )
})
}
// asyncFn('a')
// .then(()=>{return async('b')})
// .then(()=>{return async('c')})
// .then(()=>{return async('d')})
let a = ['a','b','c','d']
a.reduce((previous, current, index, array) => {
return previous // initiates the promise chain
.then(()=>{return asyncFn(array[index])}) //adds .then() promise for each item
}, Promise.resolve())
There is a new way to solve this and it's by using async/await.
async function myFunction() {
while(/* my condition */) {
const res = await db.getUser(email);
logger.log(res);
}
}
myFunction().then(() => {
/* do other stuff */
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://ponyfoo.com/articles/understanding-javascript-async-await
Bergi's suggested function is really nice:
var promiseWhile = Promise.method(function(condition, action) {
if (!condition()) return;
return action().then(promiseWhile.bind(null, condition, action));
});
Still I want to make a tiny addition, which makes sense, when using promises:
var promiseWhile = Promise.method(function(condition, action, lastValue) {
if (!condition()) return lastValue;
return action().then(promiseWhile.bind(null, condition, action));
});
This way the while loop can be embedded into a promise chain and resolves with lastValue (also if the action() is never run). See example:
var count = 10;
util.promiseWhile(
function condition() {
return count > 0;
},
function action() {
return new Promise(function(resolve, reject) {
count = count - 1;
resolve(count)
})
},
count)
I'd make something like this:
var request = []
while(count<10){
request.push(db.getUser(email).then(function(res) { return res; }));
count++
};
Promise.all(request).then((dataAll)=>{
for (var i = 0; i < dataAll.length; i++) {
logger.log(dataAll[i]);
}
});
in this way, dataAll is an ordered array of all element to log. And log operation will perform when all promises are done.
First take array of promises(promise array) and after resolve these promise array using Promise.all(promisearray).
var arry=['raju','ram','abdul','kruthika'];
var promiseArry=[];
for(var i=0;i<arry.length;i++) {
promiseArry.push(dbFechFun(arry[i]));
}
Promise.all(promiseArry)
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
function dbFetchFun(name) {
// we need to return a promise
return db.find({name:name}); // any db operation we can write hear
}
Use async and await (es6):
function taskAsync(paramets){
return new Promise((reslove,reject)=>{
//your logic after reslove(respoce) or reject(error)
})
}
async function fName(){
let arry=['list of items'];
for(var i=0;i<arry.length;i++){
let result=await(taskAsync('parameters'));
}
}
function promiseLoop(promiseFunc, paramsGetter, conditionChecker, eachFunc, delay) {
function callNext() {
return promiseFunc.apply(null, paramsGetter())
.then(eachFunc)
}
function loop(promise, fn) {
if (delay) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, delay);
})
.then(function() {
return promise
.then(fn)
.then(function(condition) {
if (!condition) {
return true;
}
return loop(callNext(), fn)
})
});
}
return promise
.then(fn)
.then(function(condition) {
if (!condition) {
return true;
}
return loop(callNext(), fn)
})
}
return loop(callNext(), conditionChecker);
}
function makeRequest(param) {
return new Promise(function(resolve, reject) {
var req = https.request(function(res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
resolve(data);
});
});
req.on('error', function(e) {
reject(e);
});
req.write(param);
req.end();
})
}
function getSomething() {
var param = 0;
var limit = 10;
var results = [];
function paramGetter() {
return [param];
}
function conditionChecker() {
return param <= limit;
}
function callback(result) {
results.push(result);
param++;
}
return promiseLoop(makeRequest, paramGetter, conditionChecker, callback)
.then(function() {
return results;
});
}
getSomething().then(function(res) {
console.log('results', res);
}).catch(function(err) {
console.log('some error along the way', err);
});
How about this one using BlueBird?
function fetchUserDetails(arr) {
return Promise.each(arr, function(email) {
return db.getUser(email).done(function(res) {
logger.log(res);
});
});
}
Here's another method (ES6 w/std Promise). Uses lodash/underscore type exit criteria (return === false). Note that you could easily add an exitIf() method in options to run in doOne().
const whilePromise = (fnReturningPromise,options = {}) => {
// loop until fnReturningPromise() === false
// options.delay - setTimeout ms (set to 0 for 1 tick to make non-blocking)
return new Promise((resolve,reject) => {
const doOne = () => {
fnReturningPromise()
.then((...args) => {
if (args.length && args[0] === false) {
resolve(...args);
} else {
iterate();
}
})
};
const iterate = () => {
if (options.delay !== undefined) {
setTimeout(doOne,options.delay);
} else {
doOne();
}
}
Promise.resolve()
.then(iterate)
.catch(reject)
})
};
Using the standard promise object, and having the promise return the results.
function promiseMap (data, f) {
const reducer = (promise, x) =>
promise.then(acc => f(x).then(y => acc.push(y) && acc))
return data.reduce(reducer, Promise.resolve([]))
}
var emails = []
function getUser(email) {
return db.getUser(email)
}
promiseMap(emails, getUser).then(emails => {
console.log(emails)
})

Chaining more than two tasks using deferred and can this be use for loops?

I am getting used to $.Deferred just now, and it happens that I needed to chain three tasks using $.Deferred - then.
I created a function:
function processA(param1, param2) {
log = $.post('http://domain.com/process',
{
id: param1,
another: param2
}
),
set = log.then(function(html){
if (someCondition) {
console.log('Successful');
// i want to do another ajax call here
// and chain another, that does an ajax again
}
})
}
How do I do that, as stated in the comments of my code.
Is it right? Not tested, just thought while typing this.
set = log.then(function(html){
if (someCondition) {
console.log('Successful');
$.post(....),
def = set.then(function(data){
// i want to do another thing here.
})
}
})
And another thing, is it possible to use the function in a loop?
e.g.
data = [{param1:"...", param2:"..."}, {..., ...}]
$.each(data, function(k,v){
processA(v.param1, v.param2);
})
Here better explained chaining promises:
function authenticate() {
return getUsername()
.then(function (username) {
return getUser(username);
})
// chained because we will not need the user name in the next event
.then(function (user) {
return getPassword()
// nested because we need both user and password next
.then(function (password) {
if (user.passwordHash !== hash(password)) {
throw new Error("Can't authenticate");
}
});
});
}
This is something I wrote for a dice game. Rolling the dice, each dice.roll() gets stored into a $.Deferred object. When all dice have run their animation, you can execute your callbacks or whatever.
var promises = [];
// collect promises
_.each(fDice, function (die) {
promises.push(function () {
return $.Deferred(function (dfd) {
$(die).roll(options, function (data) {
dfd.resolve(data); // resolve the state
});
}).promise(); // send it back
});
});
// roll selected dice
dfrAll(promises).done(function () {
// do something here
});
dfrAll: function (array) {
/// <summary>Resolves n $.Deferred functions from an Array</summary>
/// <param name="Array" type="Array">An Array of $.Deferred functions</param>
/// <returns type="Deferred" />
var dfd = $.Deferred(),
len = array.length,
results = [];
if (len === 0) {
dfd.resolve(results);
} else {
for (var i = 0; i < len; i++) {
var promise = array[i];
$.when(promise()).then(function (value) {
results.push(value);
if (results.length === len) {
dfd.resolve(results);
}
});
}
}
return dfd.promise();
}
For me the storage of deferred functions into an array was the key to resolve my animations. Hope it helps.

Categories

Resources