奇怪的 for 循环问题

2016-08-16 14:03:18 +08:00
 InFaNg

代码如下,每次运行后items中只有i=100时的情况

var express = require('express');
var cheerio = require('cheerio');
var superagent = require('superagent');
var items = [];

var app = express();
for(var i=1;i<100;i++) {
  app.get('/', function (req, res, next) {
    superagent.get('http://xxx/' + i + '.html')
      .end(function (err, sres) {
        if (err) {
          return next(err);
        }
        var $ = cheerio.load(sres.text);
        items.push($('.d1').attr('href'));
        res.send(items);
      });
  });
}

app.listen(3000, function () {
  console.log('app is listening at port 3000');
});
2449 次点击
所在节点    Node.js
13 条回复
bdbai
2016-08-16 14:10:33 +08:00
这是闭包教程的经典例子😂
另外你这个逻辑似乎有点问题,回去重新写一下。
lijsh
2016-08-16 14:16:53 +08:00
这个和闭包无关,你这里相当于创建了 100 个 app.get('/', fn)的路由处理, url 都一样的,估计是最后一个才起效。

这里都不用 express ,你直接用 superagent 不就行了。
wodesuck
2016-08-16 15:36:13 +08:00
没点进来就知道是这样😂
因为你里面的 function 实际是在 for 循环结束之后执行的,那时候 i 已经改变了
for (var i ...) {
function(i) {
...
}(i);
}
试一下这样,把 i 作为参数传进去,可以避免受外部的 for 影响
bdbai
2016-08-16 15:37:09 +08:00
给你一个改过的例子,用了一些略带花哨的 ES6 特性。要抓的东西你自己改一下吧。

https://gist.github.com/bdbai/3c4d1507c47874efe002683465a7bc25
zhqy
2016-08-16 17:05:37 +08:00
@lijsh 你这第一句话全说错了。
Arrowing
2016-08-16 17:12:19 +08:00
看了标题就想到了结果,果然是这样 😂
还是闭包的问题啊。
phxsuns
2016-08-16 17:17:49 +08:00
是你的逻辑有点怪。
创建了 100 个路由处理,还是同一个路由。
那肯定只有一个结果了。
zhouyg
2016-08-16 17:46:45 +08:00
猜猜,果然就是闭包和异步引用的问题。
isbase
2016-08-16 18:08:36 +08:00
用 ES6 的 let

var express = require('express');
var cheerio = require('cheerio');
var superagent = require('superagent');
var items = [];

var app = express();
for(var i=1;i<100;i++) {
let j = i;
app.get('/', function (req, res, next) {
superagent.get('http://xxx/' + j + '.html')
.end(function (err, sres) {
if (err) {
return next(err);
}
var $ = cheerio.load(sres.text);
items.push($('.d1').attr('href'));
res.send(items);
});
});
}

app.listen(3000, function () {
console.log('app is listening at port 3000');
});
Biwood
2016-08-16 18:27:59 +08:00
这种基础的 JS 面试常见知识点在 V2 论坛都快成月经贴了
xcodebuild
2016-08-16 19:15:15 +08:00
InFaNg
2016-08-16 19:24:32 +08:00
@phxsuns for 写错位置了。。。。
m31271n
2016-08-17 16:16:39 +08:00
看见标题,想到结果系列。

涉及到的知识点:
* var 的特性
* 块级作用域
* 作用域链

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/299630

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX