te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>ecmascript 6 - What's the difference between generators and closures in JavaScript? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ecmascript 6 - What's the difference between generators and closures in JavaScript? - Stack Overflow

programmeradmin4浏览0评论

What's the difference between doing these two solutions to the same problem?

Closure Method

const numberIncrementer = startValue => () => startValue++
const getNextNumber = numberIncrementer(0)

console.log(getNextNumber())
// 0

console.log(getNextNumber())
// 1

console.log(getNextNumber())
// 2

Generator Method

const numberIncrementer = function*(startValue) {
    while(true) {
        yield startValue++
    }
}

const numberFactory = numberIncrementer(0)
const getNextNumber = () => numberFactory.next().value

console.log(getNextNumber())
// 0

console.log(getNextNumber())
// 1

console.log(getNextNumber())
// 2

Viewing these two methods, what reason do I have to choose one over the other?

What's the difference between doing these two solutions to the same problem?

Closure Method

const numberIncrementer = startValue => () => startValue++
const getNextNumber = numberIncrementer(0)

console.log(getNextNumber())
// 0

console.log(getNextNumber())
// 1

console.log(getNextNumber())
// 2

Generator Method

const numberIncrementer = function*(startValue) {
    while(true) {
        yield startValue++
    }
}

const numberFactory = numberIncrementer(0)
const getNextNumber = () => numberFactory.next().value

console.log(getNextNumber())
// 0

console.log(getNextNumber())
// 1

console.log(getNextNumber())
// 2

Viewing these two methods, what reason do I have to choose one over the other?

Share Improve this question edited Sep 8, 2017 at 15:28 Kevin Ghadyani asked Sep 8, 2017 at 15:22 Kevin GhadyaniKevin Ghadyani 7,2978 gold badges47 silver badges66 bronze badges 11
  • Well the syntax is pletely different? And try to do anything a bit more plex than an infinite loop… – Bergi Commented Sep 8, 2017 at 15:33
  • 1 There is tons of overlap in many APIs. In this example, the differences aren't really shown -- especially since it appears a closure is being created by the generator. The main differences e up in terms of async flow. While you have the .next() method hard coded into your getNextNumber function, it would perhaps more appropriately be outside of that function so you can call next() after some async work returns with data. But i could be wrong about all of this... – Pytth Commented Sep 8, 2017 at 15:34
  • 1 Functionally speaking, one big difference is that Generators produce Iterators, so you can use for..of to iterate over the data a generator produces. Another difference as that with the Generator you could process an infinite sequence. – Rob M. Commented Sep 8, 2017 at 15:39
  • 3 Closures are sort of higher order functions and hence very powerful. It wouldn't surprise me, if they are equally expressive as generators in many scenarios. A closure provides state between function calls, which is stored on the heap and can consume (arguments) and produce (return) values. Sounds a lot like generators, at least technically. It's probably awkward in plex scenarios to maintain state like generators do, though. – user6445533 Commented Sep 8, 2017 at 18:15
  • 1 To me it seems like paring apples with oranges. Generators are basically syntactic sugar for creating iterators. Closures are functions that have free variables. Generator functions can be closures. – Felix Kling Commented Sep 8, 2017 at 21:01
 |  Show 6 more ments

2 Answers 2

Reset to default 14

In the following contrived example I convert an Object into a Map without relying on an intermediate Array:

function* entries(o) {
  for (let k in o) yield [k, o[k]];
}

const m = new Map(entries({foo: 1, bar: 2}))

console.log(
  Array.from(m) // [["foo", 1], ["bar", 2]]
);

This doesn't work with a closure, as you cannot access the state of the for/in loop to maintain it across function calls. The state is encapsulated within the loop construct. So there are cases that can be expressed with generators but not with closures.

Adding to a previous answer: while there might be cases that can be expressed with generators but not with closures (I was looking for that answer as well), the one demonstrated by user6445533 is not one of them. Here is it, done with closures:

const entries = (o) => ({
  entries: Object.entries(o),
  next() {
    return this.entries.length
      ? { value: this.entries.shift() }
      : { done: true };  
  },
  [Symbol.iterator]() {
    return this;
  }
});

const m = new Map(entries({foo: 1, bar: 2}));

console.log(Array.from(m)); // [["foo", 1], ["bar", 2]]

So, maybe it's all syntactic sugar in the end?

发布评论

评论列表(0)

  1. 暂无评论