还在为不知道怎么使用 DeepSeek 而发愁吗?别担心,看完这篇文章,你就能轻松掌握 DeepSeek 的使用技巧,开启高效创作之旅!

一、一分钟,开启 DeepSeek 探索之旅
注册 DeepSeek 超简单,一分钟就能搞定!
打开 https://chat.deepseek.com/sign_up,输入手机号,密码,点击发送验证码。要是没收到验证码,就等下再重试一次。恭喜你,成功迈出第一步!
自由人博客
还在为不知道怎么使用 DeepSeek 而发愁吗?别担心,看完这篇文章,你就能轻松掌握 DeepSeek 的使用技巧,开启高效创作之旅!
注册 DeepSeek 超简单,一分钟就能搞定!
打开 https://chat.deepseek.com/sign_up,输入手机号,密码,点击发送验证码。要是没收到验证码,就等下再重试一次。恭喜你,成功迈出第一步!
JS引擎内部转换为原始值ToPrimitive(obj,preferredType)函数接受两个参数,第一个obj为被转换的对象,第二个preferredType为希望转换成的类型(默认为空,接受的值为Number或String)
在执行ToPrimitive(obj,preferredType)时如果第二个参数为空并且obj为Date的实例时,此时preferredType会被设置为String,其他情况下preferredType都会被设置为Number
如果preferredType为Number,ToPrimitive执行过程如下:
如果preferredType为String,将上面的第2步和第3步调换,即:
我写的一个ToPrimitive函数可以在这里查看 >> JS Bin – Collaborative JavaScript Debugging
lsof -i:3000 | grep node | awk '{ print $2 }' | xargs kill
lsof -i:3000
列出所有占用3000端口的文件
grep node
过滤结果,使其只包含有node的行
awk '{ print $2 }'
awk对每一行进行处理 ,以空白符(空格、tab等)将每行数据分割,$0为所有数据,$N为第N列
xargs kill
xargs将管道中的读取的数据作为参数传递给kill
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}' name,shell root,/bin/bash daemon,/bin/sh bin,/bin/sh sys,/bin/sh .... blue,/bin/nosh
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
content-disposition
header为null在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,
如果要访问其他头,则需要服务器设置Access-Control-Expose-Headers
Access-Control-Expose-Headers:Content-Disposition
fetch(`${url}`, {
method: 'POST',
headers: {
...
},
mode: 'cors',
body: JSON.stringify({
companyId: this.state.params.companyId,
startDate: this.state.listParams.startDate,
endDate: this.state.listParams.endDate,
})
}).then(res => res.blob().then(blob => {
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob); // 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)
let disposition = res.headers.get('content-disposition');
let filename = (disposition && disposition.replace(/attachment;.*filename=/, '')) || 'uv.xls'
console.log('disposition:', disposition)
console.log('filename:', filename)
a.href = url;
a.download = filename;
a.click();
// 使用完ObjectURL后需要及时释放, 否则会浪费浏览器存储区资源.
window.URL.revokeObjectURL(url);
}))
}
身处技术圈,前端技术真的是日新月异,异步的实现方式从callback、到Promise、再到Generator、Async/Await,有了长足的发展,Promise作为发展过程中的一种产物其既是callback的一种改良,也是Generator、Async/Await的基础。
直接import一个Promise类库当然可行(在支持的浏览器中直接使用Promise也未尝不可),但是如果我们能够亲手实现一个Promise,那么我们还能够:
另外有一点需要说明,本文针对的是有一定Promise基础的同学,基础知识不在本文范畴之内,不了解的话请自行Google :)
实现之前我们先来思考下,一个Promise中到底有哪些是必须要实现的?
按照Promise/A+的标准来说,只需要Promise的then方法即可,至于怎么实现、constructor怎么写,完全没有提及。不过虽然看似东西很少,但是实质上还是有蛮多东西要处理的。
首先,constructor是必须的,在这里我们需要做一些初始化的动作:
其次,then方法由于是每个实例上都有,所以会挂在prototype上面,then方法中我们需要做的事情有
然后,我们还需要一个resolvePromise函数,这个函数根据标准而来(其实不管怎样,Promise的实现中都是少不了这样的处理过程)
至于原型上的catch方法以及race、all等静态方法,暂时不处理,而且这些在我们实现了Promise的基础代码后都是很容易的事情,暂时不做处理。
function Promise(resolver) { var self = this self.status = 'pending' self.fulfilledCallbacks = [] self.rejectedCallbacks = [] self.data = null if(typeof resolver !== 'function') { throw new TypeError('Promise resolver ' + resolver + 'is not a function') } function onFulfilled(data) { setTimeout(function () { if(self.status !== 'pending') return self.status = 'fulfilled' self.data = data var currentCallback for(var i = 0; i < self.fulfilledCallbacks.length; i++) { currentCallback = self.fulfilledCallbacks[i] typeof currentCallback === 'function' && currentCallback(self.data) } }) } function onRejected(reason) { setTimeout(function () { if(self.status !== 'pending') return self.status = 'rejected' self.data = reason var currentCallback for(var i = 0; i < self.rejectedCallbacks.length; i++) { currentCallback = self.rejectedCallbacks[i] typeof currentCallback === 'function' && currentCallback(self.data) } }) } try { resolver(onFulfilled, onRejected) }catch (e){ onRejected(e) } }
可以看到,在构造函数中最上面是对初始状态的处理。
self.status = 'pending' // 初始化时必定是pengding状态, self.fulfilledCallbacks = [] // fulfilled后执行的回调 self.rejectedCallbacks = [] // rejected后执行的回调 self.data = null // 初始化时Promise内部的数据
接着对resolver做了判断,
if(typeof resolver !== 'function') { throw new TypeError('Promise resolver ' + resolver + 'is not a function') }
因为对于一个Promise来说,传入的resolver不是function就没有意义了,比如
var p = new Promise(100) //那么这里传入100的时候,到底想干嘛?
然后是onFulfilled和onRejected这两个函数的定义,即我们传递给一个Promise实例里的resolve和reject两个参数
var p = new Promise( (resolve, reject) => { resolve() // resolve即onFulfilled、reject即onRejected })
function onFulfilled(data) { setTimeout(function () { if(self.status !== 'pending') return self.status = 'fulfilled' self.data = data var currentCallback for(var i = 0; i < self.fulfilledCallbacks.length; i++) { currentCallback = self.fulfilledCallbacks[i] typeof currentCallback === 'function' && currentCallback(self.data) } }) }
在onFulfilled中首先我们看到的是一个setTimeout,这样做的目的是为了确保onFulfilled是异步执行的,至于为何要异步执行,目前还没有搞懂,个人感觉是非必须的,但是如果设置为同步的会导致测试无法通过,在查看bluebird的源代码时发现这部分根据data做了判断,如果非Promise会是同步,而是Promise的话会异步执行,这个坑先留着,待后面解决。
setTimeout内先对状态进行判断,如果其已经是fulfilled或rejected我们直接返回,接着就是一个for循环执行回调。
onRejected和onFulfilled大同小异,不多赘述。
try { resolver(onFulfilled, onRejected) }catch (e){ onRejected(e) }
最后我们直接在一个try/catch中执行传入的resolver,以便对执行resolver时候的错误进行处理。
Promise.prototype.then = function (onFulfilled, onRejected) { var self = this var p onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(val){return val} onRejected = typeof onRejected === 'function' ? onRejected : function(reason){throw reason} if(self.status !== 'pending') { return p = new Promise(function (resolve, reject) { setTimeout(function () { var functionToCall = self.status === 'fulfilled' ? onFulfilled : onRejected var result try { result = functionToCall(self.data) resolvePromise(p, result, resolve, reject) } catch (e) { reject(e) } }) }) } else { return p = new Promise(function (resolve, reject) { self.fulfilledCallbacks.push(function(){ try { var result = onFulfilled(self.data) // 如果上个then的返回值是个Promise实例 或者Promise resolver里面resolve的结果是个Promise实例 resolvePromise(p, result, resolve, reject) } catch (e) { reject(e) } }) self.rejectedCallbacks.push(function(){ try { var result = onRejected(self.data) // 如果上个then的返回值是个Promise实例 或者Promise resolver里面resolve的结果是个Promise实例 resolvePromise(p, result, resolve, reject) } catch (e) { reject(e) } }) }) } }
根据标准Promise.prototype.then的返回值是一个新的Promise,所以我们可以看到2处类似这样的代码
return p = new Promise(function (resolve, reject) { ... })
这2处就是根据当前Promise实例(self)的状态来做不同的处理
首先看非pending状态
接着再看pending,由于self还是pending状态,那么就等到self resolve或者是reject的时候再来处理,即将相应的代码放入fulfilledCallbacks/rejectedCallbacks中即可
function resolvePromise(promise, x, resolve, reject){ var then var thenCalled if(promise === x) reject(new TypeError('Chaining cycle detected for promise!')) if(x instanceof Promise) { if(x.status === 'pending') { x.then(function (value) { resolvePromise(promise, value, resolve, reject) }, reject) }else{ x.then(resolve,reject) } } else if(x !== null && (typeof x === 'function' || typeof x === 'object') ){ try{ then = x.then if(typeof then === 'function') { then.call(x, function(y){ if(thenCalled) return thenCalled = true resolvePromise(promise, y, resolve, reject) }, function(r){ if(thenCalled) return thenCalled = true return reject(r) }) } else { resolve(x) } }catch(e){ if(thenCalled) return thenCalled = true return reject(e) } }else{ resolve(x) } }
刚开始的时候不是很立即为什么会有这么一个过程,想着直接根据then中onFulfilled返回的值(result)做判断,然后返回不同的Promise即可,后来发现result有各种不同的情况,而且不止一个地方需要用到,那么将其抽取出来是就合情合理了。
resolvePromise中主要的处理就是根据传入的x来决定promise(输入参数中的promise)的状态,其中最主要的2块
其他代码更多的是边界值的判断,这里就不做赘述了。
之前面试的时候被问到怎么实现一个Promise,一脸懵逼,这个问题压根没想过,然后临阵发挥的时候一直纠结于resolve在哪里,现在想想真是傻,为何为停在这里。。。🙃
参考资料
主要知识点:
另外关于Function和Object比较特殊的点:
参考文章:
因为这个功能在2.1.4中还没有,所以乖乖去下吧,不然打破头皮也没用。
下载地址在这里: iTerm2 最新稳定版
当然版本可能会更新,所以你也可以在这里找最新的地址:https://iterm2.com/downloads.html
安装我就不多说了,和其他APP的安装一样,解压到应用程序文件夹就可以了。
然后,打开 Preference>Advanced>Enable session restoration
iterm2-Session Restoration
有一点需要注意:我在装完这个beta版之后上面截图的选项默认已经是Yes,但是特么的没有一点效果,在将这个选项关掉,退出,然后再打开,再退出,然后才有效。所以如果你也遇到这个问题,试试我的这个方法吧。
打开Preference>General,然后设置Startup为 Use System Window Restoration Setting
iterm2-Startup
没错,还要修改系统设置,因为这是iterm2利用的系统特性才能完成的功能。
打开 系统偏好设置>通用,把退出应用时关闭窗口选项关掉。
iterm2-系统设置