总结几个最近遇到的问题

最近看了些文章,遇到了写问题,花了点时间总结如下。


localhost 和 127.0.0.1

一般情况下,我们的电脑可能有三块网卡。分别是🌹:

  1. 一块叫 loopback 的虚拟网卡
  2. 一块叫 ethernet 的有限网卡
  3. 一块叫 wlan 的无限网卡

我们电脑的本机 IP ,可以理解为时真实网卡的 IP, 有限和无限分别有一个。是网络出口IP。

现在主要是了解下这个 虚拟的网卡 loopback 它是什么,以及它和 127.0.0.1 的关系。

127.0.0.1 到 127.255.255.255整个都是环回地址(loopback),用来测试本机的TCP/IP协议栈,发往这段A类地址数据包不会出网卡,网络设备不会对其做路由, 也就是只在本地做回环访问,故只能本机访问。

所以环回地址是主机用于向自身发送通信的一个特殊地址,是一个特殊的目的地址。因此如果一台主机上的两项服务如果使用的是环回地址而非分配的主机地址,就可以绕开 TCP/IP 协议栈的下层,不用再通过链路层,物理层,以太网等传出去。

而localhost 是一个 域名,一般指向 127.0.0.1, 实际上它也可以指向任何一个ip, 可以去系统文件中修改

之所以去了解这个,其实是因为最近踩了下面个坑,顺带也去了解了下这个。


whistle 转发 header host 被更改问题

❎同事B为了在页面内 include 一个 php cgi 返回的 token, 希望能够在 apache 里面配置代理转发,当看到了这个include的 cgi 后,即转发到对应的 机器上。

她发现 php 的接口已经成功转发到测试机器上,但是返回的内容不正常,在帮她调试接口后,发现后台接口验证了 Valid Host, 而她的 host 还是本机的 localhost。

她相关的whistle 配置为:

1
pay.qq.com  localhost/wechat_h5/dist/h5/store/views/

可以通过 pay.qq.com/index.shtml 直接访问到对应的本地页面。但是为什么 header 里面的 host 竟然不是 pay.qq.com 而是 localhost 呢?❌

这里是由于 whistle 导致的。

whistle 对于上面这种配置,会认为是一个 rule, 直接整个链接类似被 302 跳转了,导致了 header 里的 host 也被修改为了 localhost, 所以不能通过接口校验。

需要改成如下配置:

1
pay.qq.com/wechat_h5/dist/h5/store/views/ localhost

这种情况,whistle 会认为这是一个 host 代理, header 里面的内容不会受影响

两种类似相似的写法,还是有不一样的效果,如果不是这种后台会验证 valid host 的情况,两种都可以用。


es6-promise 不支持 finally?

es6-promise 是一个比较好的 promise polyfill 库 ,但是遗憾的是目前它还不支持 finally,如果用 es6-promise ,又想用 finally ,怎么办呢?可以简单的用 then 来代替 finally

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
printPersonFullName() {
return fetch('./data/person.json')
.then(response => {
return response.json();
})
.then(person => {
console.log(`${person.firstName} ${person.lastName}`);
})
.catch(e => {
console.log('error')
})
.then(() => {
console.log('finally');
})
}

这样最后一个 then 方法一定会进入,及时之前 catch 到了 error。可以简单的来替代 finally。


神奇的translate3d

ios safari 下,如果你经常用 position: fixed, 可能会遇到一些奇奇怪怪的问题,比如页面卡住,页面白屏等问题。

这时候你可以试试神奇的 translate3d, 它会触发 GPU 的重新加速。

1
2
3
4
5
6
7
8
.Element-header {
transform: translate3d(0,0,0);
}

.Element-header--fixed {
top: 0;
position: fixed;
}

不太了解 CSS 的我,靠这个解决了很多问题。相关参考文章

建议是safari中能不用fixed就不用 fixed


Promise Anti-patterns

最近看了一篇文章,讲的不错,大概讲的就是说常见的一些错误的 Promise 用法。在这里记录下,供自己经常翻看。原文章地址在此。

Nested Promises

1
2
3
4
5
loadSomething().then(function(something) {
loadAnotherthing().then(function(another) {
DoSomethingOnThem(something, another);
});
});

To fix:

1
2
3
4
q.all([loadSomething(), loadAnotherThing()])
.spread(function(something, another) {
DoSomethingOnThem(something, another);
});

The Broken Chain

1
2
3
4
5
6
7
8
function anAsyncCall() {
var promise = doSomethingAsync();
promise.then(function() {
somethingComplicated();
});

return promise;
}

To Fixed:

1
2
3
4
5
6
function anAsyncCall() {
var promise = doSomethingAsync();
return promise.then(function() {
somethingComplicated()
});
}

The Collection Kerfuffle

1
2
3
4
5
6
7
8
9
10
11
12
13
function workMyCollection(arr) {
var resultArr = [];
function _recursive(idx) {
if (idx >= resultArr.length) return resultArr;

return doSomethingAsync(arr[idx]).then(function(res) {
resultArr.push(res);
return _recursive(idx + 1);
});
}

return _recursive(0);
}

To fix, use map & reduce:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function workMyCollection(arr) {
return q.all(arr.map(function(item) {
return doSomethingAsync(item);
}));
}

// or you want them in series
function workMyCollection(arr) {
return arr.reduce(function(promise, item) {
return promise.then(function(result) {
return doSomethingAsyncWithResult(item, result);
});
}, q());
}

The Ghost Promise

1
2
3
4
5
6
7
8
9
var promise;
if (asyncCallNeeded)
promise = doSomethingAsync();
else
promise = Q.resolve(42);

promise.then(function() {
doSomethingCool();
});

To fix:

1
2
3
4
5
6
7
8
9
10
// 用 Q 包一层
Q(asyncCallNeeded ? doSomethingAsync() : 42)
.then(
function(value){
doSomethingGood();
})
.catch(
function(err) {
handleTheError();
});

The Overly Keen Error Handler

1
2
3
4
5
6
7
somethingAsync.then(
function() {
return somethingElseAsync();
},
function(err) {
handleMyError(err);
});

To fix :

1
2
3
4
5
6
7
8
// 避免上面fufilled内的error不被 catch 到
somethingAsync
.then(function() {
return somethingElseAsync();
})
.catch(function(err) {
handleMyError(err);
});

The Forgotten Promise

1
2
3
4
5
6
7
8
9
var deferred = Q.defer();
doSomethingAsync().then(function(res) {
res = manipulateMeInSomeWay(res);
deferred.resolve(res);
}, function(err) {
deferred.reject(err);
});

return deferred.promise;

To fix:

1
2
3
4
// 避免上述无意义的创建 promise
return doSomethingAsync().then(function(res) {
return manipulateMeInSomeWay(res);
});


总结

看了一些文章,其实多看看这些总结类的文章,然后自己把自己工作中遇到的问题总结出来是个很好的事情,梳理了自己的脑袋瓜哈哈。 今天好累啊,可能是生病的原因,早点回家了。9点20。给老妈打个☎️,回去再看看书,遛遛狗🐩,完美😊~