I have an
ids object, which maps
id strings to
for id of ids product = ids[id] console.log product # Prints out something different each loop. :) Product.create(product).then -> console.log product # Only prints out the last id each loop. :(
I'm using a library for database interactions, which exposes promises (indicated by the
then function above). I'm trying to print out the
product variable inside the
then function, but I only seem to be getting the last
ids, so it looks like it's a scoping issue. How can I scope the
product variable properly so that it prints out a different product in the
then function each loop?
@false did find the right duplicate describing your issue. Indeed, you've got a scoping issue where
product is non-local to the loop body, and you get the last item only from your asynchronous callbacks.
How can I scope the product variable properly so that it prints out a different product in the then callback?
In idiomatic coffeescript, you will use the
do notation for the IEFE in the loop:
for id of ids do (product = ids[id]) -> console.log product Product.create(product).then -> console.log product
Or, drawing the property value directly from the
for id, product of ids do (product) -> …
Bergi's code is misleading IMO since it runs the whole loop at once, not sequentially. For that reason I would just lift all the code to work in promises instead of mixing sync and async:
Promise.resolve(product for _, product of ids).then next = (products) -> [product, products...] = products if product console.log product Product.create(product).then -> console.log product next products .then -> console.log "all done"
The difference is:
then ->runs only after the loop has completed completely
These properties of a real loop are much more important than superficial syntax which you can learn in a couple of days.
Let it run and look at the difference in the logs.
©2020 All rights reserved.