Is .then(function(a){ return a; }) a no-op for promises?
It seems to me like
.then(function (a) { return a; })
is just a no-op. Right?
Yes.1
It is useless and should be omitted.
What's going on and why did the author write it that way?
It's a blunder. Or the author didn't understand promises.
1: If they aren't the same, what's the difference?
As always, there are some edge cases. Really weird ones. That no-one should use (without extensive commenting):
a) it returns a new promise instance, a distinct object, to avoid sharing. However, .then()
would as well.
b) a
is tested again for its thenable-ness. If it suddenly became a promise since the fulfillment, it now will be awaited. This would be awful of course.
What's the syntax for a no-op Promise in Parse?
With all "dirty" outcomes contributing a resolved promise to the aggregation, you can choose for each "clean" outcome to contribute in any of the following ways :
- not to put anything in the array,
- put a value in the array,
- put a resolved promise in the array,
- put a rejected promise in the array.
(1), (2) and (3) will guarantee that the aggregated promise resolves regardless of the clean/dirty outomes (except some unpredicted error).
(4) will cause the aggregared promise to resolve only if all outcomes are "dirty", or to reject as soon as any one "clean" outcome arises.
Realistically, the choice is between (2) and (4), depending on how you want the aggregated promise to behave. (1) would complicate the aggregation process, and (3) would be unnecessarily expensive.
It would seem appropriate for the aggregated promise to resolve when everything is either already "clean" or has been cleaned up, therefore I would suggest (2), in which case your foo()
/bar()
/quux()
functions could be written as follows :
function foo() {
return recipe.dirty('imageFile') ? updates_thumbnails() : true; // doesn't have to be `true` or even truthy - could be almost anything except a rejected promise.
}
And aggregate the outcomes as in the question :
$.when([ foo(recipe), bar(recipe), quux(recipe) ]).then(function() {
//all thumbnails were successfully updated.
}).fail(function() {
//an unexpected error occurred in foo(), bar() or quux().
});
confused with .then() in promises
You need to add return
to inside your chains when you're calling those functions. For example:
function login() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({username : 'default'})
}, 1000)
})
}
function getVideos() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(['vid1', 'vid2'])
},1000)
})
}
function getDesc() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('desc')
}, 1000)
})
}
const test = login()
test.then(res => {
console.log(res)
return getVideos()
})
.then(res => {
console.log(res)
return getDesc()
})
.then(res => console.log(res))
This is a good guide: https://javascript.info/promise-chaining
Filtering an array with a function that returns a promise
As mentioned in the comments, Array.prototype.filter
is synchronous and therefore does not support Promises.
Since you can now (theoretically) subclass built-in types with ES6, you should be able to add your own asynchronous method which wraps the existing filter function:
Note: I've commented out the subclassing, because it's not supported by Babel just yet for Arrays
class AsyncArray /*extends Array*/ {
constructor(arr) {
this.data = arr; // In place of Array subclassing
}
filterAsync(predicate) {
// Take a copy of the array, it might mutate by the time we've finished
const data = Array.from(this.data);
// Transform all the elements into an array of promises using the predicate
// as the promise
return Promise.all(data.map((element, index) => predicate(element, index, data)))
// Use the result of the promises to call the underlying sync filter function
.then(result => {
return data.filter((element, index) => {
return result[index];
});
});
}
}
// Create an instance of your subclass instead
let arr = new AsyncArray([1,2,3,4,5]);
// Pass in your own predicate
arr.filterAsync(async (element) => {
return new Promise(res => {
setTimeout(() => {
res(element > 3);
}, 1);
});
}).then(result => {
console.log(result)
});
Babel REPL Demo
Return type for asynchronous function
You dont need a fetch
inside a Promise
since fetch
returns a promise. Also return type of an async function or method must be the global Promise type. So changed the return type here to Promise<any>
. You can replace any
with the matching type
export const getExternalResource = async(url: string): Promise<any> => {
return await fetch(url).then(response => response.json());
};
const resource = getExternalResource('url').then(d=>d);
Related Topics
Convert JSON Array to an HTML Table in Jquery
Mongodb, Remove Object from Array
Javascript: Inline Script with Src Attribute
How to Destructure Onto an Existing Object? (JavaScript Es6)
Addeventlistener in Internet Explorer
Browser JavaScript Stack Size Limit
How to Set Focus on an Input Field After Rendering
How to Draw Smooth Curve Through N Points Using JavaScript HTML5 Canvas
Binding Arrow Keys in Js/Jquery
Center a Popup Window on Screen
What's the Easiest Way to Call a Function Every 5 Seconds in Jquery
Declaring Multiple Variables in JavaScript
Emberjs: How to Load Multiple Models on the Same Route
Hot and Cold Observables: Are There 'Hot' and 'Cold' Operators
What Techniques Can Be Used to Define a Class in JavaScript, and What Are Their Trade-Offs