Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 包含承诺的for循环中的词汇作用域?_Javascript_Coffeescript_Scope_Promise_Lexical Scope - Fatal编程技术网

Javascript 包含承诺的for循环中的词汇作用域?

Javascript 包含承诺的for循环中的词汇作用域?,javascript,coffeescript,scope,promise,lexical-scope,Javascript,Coffeescript,Scope,Promise,Lexical Scope,我有一个ids对象,它将id字符串映射到product对象 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. :( 我正在使用一个数据库交

我有一个
ids
对象,它将
id
字符串映射到
product
对象

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. :(
我正在使用一个数据库交互库,它公开承诺(由上面的
then
函数表示)。我试图在
then
函数中打印
product
变量,但我似乎只在
ids
中得到最后一个
id
,所以这看起来像是一个范围问题。如何正确地确定
product
变量的范围,以便它在
函数中打印出不同的产品,然后在每个循环中执行
函数?

@false确实找到了该变量。实际上,您遇到了一个范围问题,
product
对于循环体是非本地的,并且您只能从异步回调中获取最后一项

如何正确地定义product变量的范围,以便它在回调中打印出不同的产品

在惯用的coffeescript中,您将为循环中的IEFE使用:

for id of ids
  do (product = ids[id]) ->
    console.log product
    Product.create(product).then ->
      console.log product
或者,直接从
-循环的
中绘制属性值:

for id, product of ids
  do (product) ->
    …

Bergi的代码误导了IMO,因为它一次运行整个循环,而不是按顺序运行。出于这个原因,我将提升所有代码,使其在承诺中工作,而不是混合使用sync和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"
区别在于:

  • 与真实循环中一样,下一项在前一项完成之前不会运行
  • 与实际循环一样,下一行(只需要
    然后->
    仅在循环完全完成后运行)
实循环的这些属性比表面语法重要得多,你可以在几天内学会这些语法


让它运行并查看日志中的差异。

在本例中,特别是,@false您从何处获得
forEach
呢?@false:但coffeescript中没有任何答案?因为CS确实有一个特殊的语法元素,所以它很重要。@Bergi:coffeescript有一个调用函数的特殊语法……它不是太不一样了。但是……这仍然是一种习惯用法,不是吗?不管怎样。我认为OP不希望按顺序执行它们。当然,您可以轻松地并行运行它们,并通过
Promise.map((p代表id),Product.create)收集它们的结果
或类似内容。我的回答实际上不是关于承诺部分,而是关于结束。@Bergi我认为他甚至没有意识到这种差异(顺序与并行),我在这里是为了启发他