Lexical scoping in a for loop enclosing a promise?

前端 未结 2 1264
情书的邮戳
情书的邮戳 2021-01-28 05:17

I have an ids object, which maps id strings to product objects.

for id of ids
  product = ids[id]
  console.log product #          


        
相关标签:
2条回答
  • 2021-01-28 05:27

    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:

    • Like in a real loop, next item won't run until the previous has completed
    • Like in a real loop, the next line (just needs a 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.

    0 讨论(0)
  • 2021-01-28 05:29

    @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 of-loop:

    for id, product of ids
      do (product) ->
        …
    
    0 讨论(0)
提交回复
热议问题