分类 前端 下的文章

本篇采用倒叙法,将废话放在片尾

原因:JavaScript在浏览器中顺序而异步地执行,导致某些需要有前后顺序要求的操作失效。比如先要通过XHR获得token,再用token访问新网页,异步执行会导致访问新网页的时候用的token可能还是undefined,即此时XHR请求还没完成。

解决方案:Promise对象

参考了廖雪峰老师的博客:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

Promise的使用,在下将其归类为两种操作,创建和运行。一种创建Promise对象,另一种对Promise对象进行操作:进入下一状态或者得出结果。

Promise对象的创建:两种方法,一个是直接new,另一个利用Promise.resolve()或者Promise.reject()是创建有状态的Promise。后者两者分别对应一个Promise对象在执行成功和出错时的返回结果。从语法上允许直接向上述两个Promise方法传递一个Object,作为一个新Promise的返回结果,但是从使用上一般都是作为管道,即将结果从一个Promise传递到另一个Promise,不会用于一个全新Promise的生成。

将操作写入到Promise对象的函数中,然后就可以“运行”该Promise对象。Promise对象有一个then()方法,该方法接受一个函数作为参数,执行的工作是将传入Promise的函数体执行后,将(如果存在的)resolve的参数值作为then()方法内传入的函数的第一个参数,然后执行。结合代码解释如下:

function addBy1(a) {
  return new Promise((resolv, reject) => {
    resolv(a + 1);
  })
}

var p = addBy1(0);

首先在此创建了一个函数,命名为addBy1,接受一个参数,结合函数体可以大致猜出,该函数的功能是将传入a的值加1。

Promise对象有两种自用的返回值的方法:resolve()reject(),可以分别理解为带成功和失败状态的返回结果。在直接使用new关键字生成一个新的Promise对象时,这两个函数以参数的形式传入函数体,供不同条件下的返回使用。

实际上,可以直接将addBy1的return语句中的部分用于变量p的赋值。但是为何在这里分开呢?下面自有用处。(突然跑题)

显然,若是将addBy1函数就视作一个将传入数字加1的功能的话,应该得到相应的结果。如何得到呢?答案是使用Promise对象的运行功能。(对=>运算符略作解释:该符号用于简化匿名函数的表达,(参数列表)=>{函数体}

p.then(
  (a) => {
    console.log(a);
  }
);

然后就可以获得梦寐以求的1了。但是,显然功能不会就这么简单。Promise的妙处就在于这个then(),简要来说,它提供了在异步执行的JavaScript中执行一系列的同步操作的能力。正是有了这个功能,使得需要依赖前一个操作完成后再执行下一个操作的逻辑流程能够按照正确的时序图执行。直观地感受一下:

var p = addBy1(0);
p.then(addBy1).then(addBy1).then(addBy1).then(addBy1).then(
  (a) => {
    console.log(a);
  }
);

在执行了这一段代码后,会发现输出的结果是5:从创建变量开始,一共执行了5次addBy1函数,而初始值为0。

但是若是再使用上面的一段代码输出p中的返回值,会发现其仍然是1。理解为then()方法不会改变原始Promise对象的状态吧。

then()函数接收的参数若是返回Promise对象,就可以在后面继续接.then(),从而可以定义无限长的.then()序列。而这些then()方法又必须串行执行。这就达到了一开始的目的:串行地执行JavaScript代码。

这么一说,操作都是n+1,怎么看得出来到底是不是1+1,2+1一直到4+1呢?虽然从逻辑上似乎也找不出其他的可行执行方法,但是可以通过在第一段代码的resolv()函数之前加一句console.log(a);来验证,显然输出结果会是01234。因而拓展一下,将简单的1+1操作换为需要较长时间的,比如XHR请求一类的操作的话,就可以方便地实现时序的可控化了。

最后,上文不是有提到为什么要将addBy1操作单独提出作为一个函数吗。原因有二,其一就是上文已经用到了的,为了重复进行Promise的操作,其二就是,这是一个极好的函数式编程的入门范例。函数式编程的思想之一就是使用尽可能少的参数。比如传统的1+1会表示为var result = plus(1, 1),而函数式编程会这么想:

class Number {
  constructor(x) {this.number = x;}
  addBy1() {
    return this.number + 1;
  }
}

即在正常使用时,会这么用:

var a = new Number(1);
var result = a.addBy1();

从而得到2。在使用过程中,除开对象的声明之外,没有用到一个有参数的方法。


最近处于各种原因,开始了前端编程。。然后上手就是微信(诶,好像不对)丁丁(也不对)钉钉(啊对,就是这个了)小程序。不出所料,工作就是生物代码粘合器(2077警告)。这里即兴赋歌一段:

我有个appId 我有个appSecret (双手做插合状,并摆出夸张的面部表情) access_token

我有个access_token 我有个authCode (双手做插合状,并摆出夸张的面部表情) userId

(大雾)

虽然对于很多干这行的人来说,可能认为在下这是对工作本身的不尊重,但是这确实反映了在下在看文档的时候,看到为了获取一个userId而不得不从appIdappSecret开始一路以token换token最终拿到所需要的数据的过程中,哭笑不得的感觉。我当时不选择做前端,大概就有一部分原因在这。虽然知道出于安全角度考虑,这是较为稳妥的一种方式,但是如果深陷其中,并以其为日常的工作,显然就太有些小看程序员的能力了。(咳咳,但是砖总得要有人去搬啊)

https://blog.csdn.net/weixin_30685047/article/details/94999645

客户端传来UTF-8的表单,服务器的asp用的是GBK,因而服务器端会按照GBK编码读取表单,因而就会乱码 实际上这个时候在服务器里拿到的表单已经是被GBK处理过了的,而要显示出正确的文字,需要把GBK编解码过的文字重新编码,然后用对应的UTF-8再次解码,所以实际上对二进制做的是UTF-8解码从而得到GB2312环境下的正确显示。

原因是,在GB2312里面,汉字两字节一编码,UTF-8三字节一编码,GBK会替换一些不支持的编码为?,ASCII值为63,相当于修改了UTF-8的二进制数据,偶数个汉字运气好,奇数个汉字显然结尾的数据会被破坏,嗯,这就是原因。

解决思路显然是想办法不要让服务器先用GBK进行表单解码了,因而方法有二:

  1. 想办法拿到二进制的表单,然后直接使用正确的代码页解码;
  2. 看能不能把asp换到UTF-8的环境下吧。

起缘是为了让自己看博客看得更顺眼,就打算更改一下布局。 然后看到这个博客系统十分精简地在所有页面几乎采取了同一个文件作为模板,也就是说,牵一发而动全身。

毕加思索.jpg 这玩意儿不支持图片居中。 https://github.com/kokororin/typecho-plugin-Parsedown 加个这个插件就好了,但是似乎不支持html标签里的markdown语法。

好在主页和文章页面是分开的,还可以通过在文章区用js来仅仅更改这部分的布局。

然后就有了然后:

  1. margin, padding; float

    margin为外边距,即若margin不为负,则元素尺寸不小于原尺寸,按顺序可设置上右下左四个方向的值; padding为内边距,即若padding不为负,则元素尺寸不大于原尺寸,参数及意义同上。 且似乎仅有margin可使用auto值。

    float决定元素的浮动方向, 似乎通常只有左(left)右(right)无(none)三种情况(继承inherit本身并不是浮动方式就不包括在内了吧)。none具体是什么情况我也不清楚。

  2. 用js获取页面元素

    var elem = document.getElementById("element-id");
  3. 修改元素属性

    elem.setAttribute("attribute-name", "attribute-value");
  4. 加载页面自动执行
    window.onload = function() {
    your_functions();
    }

唔姆,大概就差不多了。 具体的例子就写在网站代码里,欢迎各位dalao前来观摩 反正问题不大,就打打补丁,不去改源码算了