Quantcast
Channel: CNode:Node.js专业中文社区
Viewing all 14821 articles
Browse latest View live

git flow流程项目周期长,如何解决不同功能发布时间顺序问题。

$
0
0

git flow大家应该都了解。如下图 粘贴图片.png

如果项目进行过程中,feature-3或者feature-2要在feature-1之前发布上线的话,如何解决。


把vue项目放入docker遇到问题,求大佬来解答

$
0
0

目前在把一个Vue的前端项目放进去docker里面,在docker里面进行webpack,然后nginx进行代理 遇到的问题: 原来build好之后的静态文件的涉及到ajax 的url需要根据docker run -e 参数来进行变量的替换,但是webpack之后,不知道涉及到 ajax的url在哪个目录,有大佬知道怎样解决这个问题吗?

备案的是域名还是服务器?或者是整个网站?

$
0
0

在A服务商买的域名,B服务商买的云服务器,域名的A服务商让去云服务器B那里备案。 这备案有什么用?如果不需要域名,网站依然可以用,只是用ip而已. 除了工信部备案外,公安部的是必须的嘛?

群里有没有大哥能帮忙内推下

$
0
0

现在春招实习生开始了,论坛里面的各位大佬能不能帮下小弟,想进BAT等一线互联网公司试试。

stomp-websocket body体过大丢失

$
0
0

如果, 基于 stomp-websocket 的 stomp 协议 链接 activeMQ, 但是在测试的过程中发现 body 体如果过大, 则会出现消息丢失的问题,请问各位大大有遇到过类似的问题嘛?

Nodejs除了和之外还有比较好的书推荐么?

$
0
0

另外,朴灵大神的第二版我去年就在微博上看到在写了,不知道现在啥进度了…

使用nodemailer模块发邮件,失败!

$
0
0

使用nodemailer模块,我用163给163发邮件,可以成功。 但是用163邮箱给qq邮箱发邮件,会报这个错误:Message failed: 554 DT:SPM 163 smtp10, 查询后 意思是:554 DT:SPM 发送的邮件内容包含了未被许可的信息,或被系统识别为垃圾邮件。请检查是否有用户发送病毒或者垃圾邮件;

要是发送给别的邮箱,又有这个问题,请问这个怎么解决呢?

egg重写博客接口

$
0
0

之前用React全家桶和Java的SpringBoot重构了自己的个人博客,虽然做出来了,但是还是初成版,自我感觉还是存在很多问题。由于对Java不是完全熟悉,所以写出来的接口可能有些瑕疵,所以最近学习了eggjs,使用了egg重写了后台接口。

项目

项目地址https://github.com/k-water/egg-blog(喜欢的请点个star^_^)

运行

#1
git clone https://github.com/k-water/egg-blog.git

#2 
cd egg-blog
npm install

#3
修改config.default.js中sequelize的配置
mysql的账号密码改为自己的

#4
npm run dev

流程

参考文档

Egg官方文档

Sequelize(英文)

Sequelize(中文)

技术选型

后台框架:Egg 数据库:Mysql 插件:egg-sequelize

接口测试

工具:PostMan

数据库设计

数据库设计跟之前的也略有不同,差别的是各实体之间的联系。 实体有

  • blogs
  • comments
  • users
  • catalogs
  • authorities(用户角色)

ER图如下

实体之间联系

开发的接口

个人总结

基于学习的态度,重写了博客的后台接口,总的来说,egg使用起来还是挺方便的,官方文档写的也很好,基本遇到问题都能在官方issue找到类似的回答,写起来有点像Java的感觉。 这次让我学习到的是,基础要扎实,像数据库的设计这方面,如果学不好,那一开始也无法下手,写出来的接口肯定也是不够好,因为要考虑返回数据格式的问题,什么接口返回什么格式等等。所以基础还是很重要的,之前学的时候一直认为没什么用,反正我又用不到,但是在实践中才发现,这些技能都是需要具备的,干起活来才能事半功倍。另外一点就是要仔细阅读文档,不要急于下手写代码,对一个框架有了初步的掌握,才去下手,那样遇到问题也能快速定位到错误的位置。 以上,就是个人的小小体会啦~

接口文档

API接口文档


新人求教: node里面的require()是怎么回事啊 后面两个括号

360 元买腾讯云服务器 6.5年.看教程

$
0
0

团购地址:https://cloud.tencent.com/act/campus/group/detail?group=23796看来可能是 kpi 压力,腾讯年前,年后一直 有优惠活动。。良心云名不虚传。 这次又是,老用户开团,,新用户参团可享。非学生也可以成功购买。 源地址: https://cloud.tencent.com/act/campus/group/index老用户开团成功后可领取 100 元通用代金劵年付 120 元,购买后可以续费两年,然后等组团结束后降低配置就可以总共花 360 元续费到 2023 年。 机房选择成都,降配时,可以返还更多时间。 机房选择成都,降配时,可以返还更多时间。 机房选择成都,降配时,可以返还更多时间。 续费链接: https://cloud.tencent.com/act/campus续费时长随意。 降低配置: https://console.cloud.tencent.com/cvm/index后台控制台 - 更多 - 云主机设置 - 调整配置。选择 1G 内存,会返还时间。 附上操作步骤:

1、登录,用新号登录

2、认证,选择QQ或者微信认证。

3、参团(如果电脑打不开,扫码用手机QQ微信等打开)

4、选择12个月送4个月 支付120块

5、进入https://cloud.tencent.com/act/campus/

6、随便输入学生信息(BUG,不走学信,赶紧上)

7、返回https://cloud.tencent.com/act/campus/

8、续费2次,分别付2次120块

9、进入https://console.cloud.tencent.com/cvm/index

10、看到主机后面 更多-云主机设置-调整配置-改成1G,时间自动延长 我选成都2024-09-25到期。

11、更多-重装系统,可以选择win2008 win2012 还可以选择其他的linux。

【杭州】杭州蚂蚁金服JAVA、前端、IOS、Android开发岗位了解一下?

$
0
0

有没有想换工作的啊?

安卓:

1.负责Android 平台支付宝客户端架构设计和研发工作;

2.Android框架开发和维护,需求开发;

3.组织团队成员学习研究新技术,分享经验,帮助团队成长。

岗位要求:

1.三年以上Android客户端开发经验,深入理解Android系统原理;

2.精通android平台下的高性能编程及性能调优;

3.优秀的逻辑思维能力、分析能力、沟通能力,有强烈的责任感和良好的团队合作精神;

4.有前端、React Native 、JS相关开发经验优先;有小程序开发经验优先

前端:

1.参与小程序核心业务和技术产品的原型设计和实现;

2.钻研各种前沿技术和创新交互,增强用户体验、开拓前端能力边界,共创极客文化。

岗位要求:

1.精通HTML5、CSS3和JavaScript语言,掌握HTTP及相关网络协议,熟悉跨终端、跨浏览器的开发模式和平台特性,了解业界技术发展状况;

2.熟悉模块化、前端编译和构建工具,熟练运用主流的移动端JS库和开发框架,有基于vue或者react框架开发的产品,了解 jquery/vue/angular/react 等常用前端类库/框架的设计原理;

3.两年以上前端相关工作经验,对一到多个专项技术领域有较深入研究;

4.掌握一种非前端开发语言并实际参与过项目;

5.有优质的技术组件产出或开源产品者优先;

6.有中大型网站前端架构、H5应用的体验与性能优化、Hybrid模式应用开发、Native应用开发等经验可作为加分项;

7.充分的产品负责人意识和项目把控能力。

IOS:

1.负责 iOS 平台支付宝客户端架构设计和研发工作;

2.iOS 框架开发和维护,需求开发。

3.组织团队成员学习研究新技术,分享经验,帮助团队成长。

岗位要求:

1.三年以上iOS客户端开发经验,精通OS X/iOS下的线程管理、网络、内存管理、GUI开发;

2.精通iOS平台下的高性能编程及性能调优;

3.优秀的逻辑思维能力、分析能力、沟通能力,有强烈的责任感和良好的团队合作精神;

4.有前端、React Native 、JS相关开发经验优先;有小程序开发经验优先;

感兴趣的邮我 shikong2014@gmail.com

md格式的文章存在数据库中,用markdown包想在浏览文章的时候解析成html代码显示,

$
0
0

图片.png文章内容是 content 图片.png添加代码后,md是变成html格式了,但是在网站中不显示 图片.png不显示成h2标题?这是怎么回事? 而且,当我刷新网站后,图片.png就变成这样了 data是我在.js文件中的一个参数,将content.content的内容转成html格式后,传入data中,在进行显示,这样怎么会改变数据库中的content.content呢? 图片.png之后想写一个js把文章内容强行加入p标签中,{{content.content}}代码在js中是不是不能识别?

var a=[]和var a={} 有什么不同啊

$
0
0

为什么有的var a= [];时 a.push(1);可以成功执行 而var a= {}不可以

JBLHM(}PA3`ISCYYKJ~Q2QY.png

关于mysql读取数据的问题:怎么才能同步数据

$
0
0

代码是这样子的 function dayUserLogin(dayTime) {

var s ;
let selectSQL = `select count(distinct(dl_account)) from data_login where DATE(dl_create_time)='${dayTime}';`;

 conn.query(selectSQL,function(err0, res0){

    if (err0) {
        console.log(err0);
    }
    console.log(res0);
    s = res0;
});
//这里要用到s来做处理 
return s;

} 现在运行的结构是还没有检索出数据就返回S了, 结果是个空值! 百度了很久有说用callback的 ,但是 dayUserLogin(“2018-03-16”, function (res0) {

console.log(res0);

}); 得到的结果还是在回调函数里面,不能取出来进行使用?

刚刚接触的node,谢谢大家了

eggjs中sequelize和mongoose插件不能同时使用

$
0
0

今天想在eggjs项目中加入egg-mongoose插件,在config文件和plugin.js中都配置了信息,可是在定义mongo model时,app.mongoose始终是undefined。 我就去掉原有的egg-sequelize插件试试,结果mongoose插件生效了。我反复试验,发现egg-sequelize和egg-mongoose不能同时使用,可是eggjs毕竟是阿里的框架,应该不会出现这个问题。 请问大家知道这个问题怎么解决吗?


用问号代替参数是什么个写法?有没有文档中有介绍的呢?

$
0
0

今天在写mysql的语句时,发现十分难写,我写的是这样的:

    var str = "INSERT INTO `user`(`ID`,`USERNAME`, `PASSWORD`,`gender`,`UPADATATIME` ,`BIO`, `avatar`) VALUES (\"\","
    str = str+ "\""+name+"\",";//name
    str = str+ "\""+password+"\",";//pasword
    str = str+ "\""+gender+"\",";//gender
    str = str+ "now(),";//updatetime
    str = str+ "\""+bio+"\",";//bio
    str = str+ "\""+avatar+"\",";//avatar
    str = str+ ";";   

算是强行凑出来的SQL语句,但是我上网查到有另一种写法如下:

            insert:'INSERT INTO User(uid,userName) VALUES(?,?)', 
            queryAll:'SELECT * FROM User',  
            getUserById:'SELECT * FROM User WHERE uid = ? ',
          };
		  module.exports = UserSQL;```

当要使用的时候:

// 建立连接 增加一个用户信息 connection.query(userSQL.insert, [param.uid,param.name], function(err, result) { if(result) { result = { code: 200, msg:'增加成功' }; }作者:sprint 链接:https://www.jianshu.com/p/0a161f341771來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

请问这种问号带参数的写法哪里可以看到文档或者说明之类的?想百度也想不到关键词没能搜出来

求助关于RN的问题,Print: Entry, ":CFBundleIdentifier", Does Not Exist

$
0
0

这个问题网上搜遍了,依旧没有找到解决办法,非常困恼,现在向论坛求助; 现在说明下我的环境 nodejs:8.10.0 mac:10.13.3 (17D102) react-native-cli: 2.0.1 react-native: 0.54.2 npm:5.6.0 yarn:1.5.1

问题: 使用react-native init Uber创建好项目,进入项目cd Uber运行 react-native run-ios, 报错:

Command failed: /usr/libexec/PlistBuddy -c Print:CFBundleIdentifier build/Build/Products/Debug-iphonesimulator/Uber.app/Info.plist
Print: Entry, ":CFBundleIdentifier", Does Not Exist

看了很多贴子,说新版本RN 需要安装对应Boost等文件。 ~/.rncache 目录下也把这几个文件下载了。 image.png但是依旧还是报这个错误。

readable事件、data事件和背压(back pressure)

$
0
0

学习Readable流的时候一直对readabledata的关系不是很清楚,经过搜索和阅读源码后算是理清一点点,现在总结如下。

streamify-your-node-program :这是目前为止我看到的最为全面细致的关于流的教程,强烈建议先阅读。)

预备知识

read()Readable流的基石,无论流处于什么模式,只要是涉及读取数据最终都会转到read()上面来,它的主要功能是:

  • 读取缓冲区数据并返回给消费者,并按需发射各种事件
  • 按需调用_read()_read()会从底层汲取数据,并填充缓冲区

它的流程大致如下:

stream_read.jpg

务必记住read()同同步的,因此它并不是直接从底层数据那里读取数据,而是从缓冲区读取数据,而缓冲区的数据则是由_read()负责补充_read()可以是同步或者异步。 nodejs内部的实现经常会调用read(0),因为参数是0所以不会破坏缓冲区中的数据和状态,但可以触发_read()来从底层汲取数据并填充缓冲区。
_read()是流实现者需要重写的函数,它从底层汲取数据并填充缓冲区(flowing模式不会填充而是直接发送给消费者),它的大致流程如下:

stream__read.jpg

注意在addChunk()后会根据情况发射readable或者data事件,然后调用read()_read(0)➞…➞addChunk()从而形成一个循环,因此一旦调用了_read()流就会默默在底层读取数据,直到数据都消耗完为止

readable事件

文档上关于readable事件的描述如下

事实上, ‘readable’ 事件表明流有了新的动态:要么是有了新的数据,要么是到了流的尾部。 对于前者, stream.read() 将返回可用的数据。而对于后者, stream.read() 将返回 null。

由此我们可以知道readable事件意味着:

  • 流有了新的数据(注意,这里只说明有了新数据,至于新数据如何读取是调用者自己的事情
  • 流到达了尾部

你可以将下面的代码保存为test.js,修改size的值并运行,观察结果有何异同

"use strict";
const size = 1; //将size设为1或undefined
const rs = require("fs").createReadStream("./test.js");
rs.on("readable", () => {
	console.log(rs.read(size));
});

总之,readable只是负责通知用户流有了新的动态,事件发生的时候是否读取数据,如何读取数据则是调用者的事情(如果一直不读取事件,则数据会存在于缓冲区中) 。 例如可以给readable注册一个回调函数,该回调函数调用无参的read(),它会读取并清空缓冲区的全部数据,这样就使得每次readable发生的时候都可以读取到最新的数据。

readable的触发时机

readable在以下几种情况会被触发:

  • onEofChunk中,且_read()从底层汲取的数据为空。这个场景意味着流中的数据已经全部消耗完
  • addChunk()中,且_read()从底层汲取的数据不为空且处于pause模式,这个场景意味着流中有新数据
  • read(n)中,且n为0是的某些情况下(在测试过程中我一直无法触发这分支,不知道是对应哪种情况)。
  • 通过on()readable添加监听器,如果此时缓冲区有数据则会触发,这个场景意味着流中已经有数据可供read()直接调用。

data事件

data事件的意义则明确很多,文档上关于readable事件的描述如下(为了更加精确这里我们引用原文)

The ‘data’ event is emitted whenever the stream is relinquishing ownership of a chunk of data to a consumer.

readable不同的是,data事件代表的意义清晰单一:流将数据交付给消费者时触发。并且会将对应的数据通过回调传递给用户。

data的触发时机

从源码来看,有两个地方会触发data事件

  • read()中,如果缓冲区此时有数据可以返回给调用者,这种情况只会在调用pipe()时候发生,如果readable()被暂停过并重新启动,此时缓冲区内残留的数据会通过read()读出然后借助data事件传递出去。

  • addChunk(),此时_read()从底层汲取的数据不为空,且满足以下条件

    • 处于flowing模式
    • 缓冲区为空
    • 处于异步调用模式

    在这种情况下,数据直接就交付给消费者了,并没有在缓冲区缓存

而文档中的说法是:

当流转换到 flowing 模式时会触发该事件。调用readable.pipe(), readable.resume() 方法,或为 ‘data’ 事件添加回调可以将流转换到 flowing 模式。 ‘data’ 事件也会在调用 readable.read() 方法并有数据返回时触发。

似乎文档跟源码不太一致?其实调用readable.pipe()readable.resume()或为 data事件添加回调,最终都会依次调用read()_read()addChunk()然后最终发射data事件

结合_read()的流程图,可以知道通过on()readabledata事件添加监听器后,程序就开始循环汲取底层数据直至消耗完为止

同时监听readabledata会怎样?

"use strict";
const rs = require("fs").createReadStream("./test.js");
rs.on("readable",()=>console.log("readable触发"));
rs.on("data",console.log);

程序输出如下:

node test.js
data触发 <Buffer 22 75 73 65 20 73 74 72 69 63 74 22 3b 0a 63 6f 6e 73 74 20 72 73 20 3d 20 72 65 71 75 69 72 65 28 22 66 73 22 29 2e 63 72 65 61 74 65 52 65 61 64 53 ... >
readable触发 null

似乎readable永远得不到数据?从上面的流程图我们知道,在addChunk()中当有新数据到来的时候,redabledata都有可能触发,那究竟触发哪个?看看addChunk()的源码

function addChunk(stream, state, chunk, addToFront) {
  //处于flowing模式,且缓冲区为空,且为异步调用时候,触发data事件	
  if (state.flowing && state.length === 0 && !state.sync) {
    state.awaitDrain = 0;
    stream.emit('data', chunk);
  } else {
    state.length += state.objectMode ? 1 : chunk.length;//更新缓冲区已有数据数量
    if (addToFront)
      state.buffer.unshift(chunk);//插入缓冲区头部
    else
      state.buffer.push(chunk);//插入缓冲区尾部

    if (state.needReadable)
      emitReadable(stream);//触发readable事件
  }
  maybeReadMore(stream, state);
}

由于为data事件添加回调会使得流进入flowing模式,因此我们的例子中,有新数据时只会发射data事件,而readable事件则流结束的时候发射一次

pipe的背压(back pressure)平衡机制

假设现在有一对ReadableWritable,要求编程实现从Readable里面读取数据然后写到Writable中。那么你面临的问题很有可能就是如果两者对数据的产生/消费速度不一致,那么需要手动协调两者速度使得任务可以完成。思路可能这样:

  • 0、Readable进入flowing模式,然后进入步骤2
  • 1,监听data事件,一旦有数据到达则进入步骤2,如果捕捉到end事件就结束任务
  • 2,将数据写入到Writable,如果返回true进入步骤1,否则进入步骤3
  • 3,Readable进入pause模式,并等待Writable发射drain事件
  • 4,如果Writable发射了drain事件,则返回步骤1

而事实上pipe()的过程和上述很相似,它的源码如下:

Readable.prototype.pipe = function(dest, pipeOpts) {
 //省略...
 var ondrain = pipeOnDrain(src);
  dest.on('drain', ondrain);//当写操作返回false的时候,正常情况下必然会在稍后触发一个drain事件
  src.on('data', ondata);
  function ondata(chunk) {
    var ret = dest.write(chunk);
    if (ret === false) {//如果写操作的返回值为false,则暂停readable流
      if (((state.pipesCount === 1 && state.pipes === dest) ||
           (state.pipesCount > 1 && state.pipes.indexOf(dest) !== -1)) &&
          !cleanedUp) {
        state.awaitDrain++;
      }
      src.pause();
    }
  }
  //省略...
  return dest;
};


function pipeOnDrain(src) {
  return function() {
    var state = src._readableState;
    if (state.awaitDrain)
      state.awaitDrain--;
    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
      state.flowing = true;//将流重新设为flowing模式
      flow(src);//将缓冲区中残留的数据读取并重新触发data事件
    }
  };
}

可以看到:

  • 当向dest写入数据返回false时,马上调用src.pause()暂停流。src.pause()将暂停事件流,但不会暂停数据生成,也就是说src此时依然汲取底层数据填充缓冲区,只是暂停发射data事件,等到缓冲区的数据量超过警戒线才会停止汲取
  • 因为写入数据返回false,因此在稍后的某个时候dest必然会发射drain事件。
  • drain事件发生后,src再次进入flowing模式自动产生数据,同时将缓冲区中的残留数据写入dest

关于pipe()还可以参考这篇文章 通过源码解析 Node.js 中导流(pipe)的实现

关于Nuxt.js服务器部署

$
0
0

这两天尝试做一下SSR,用了Nuxt.js,打包后在服务器上终端npm start运行,问题是会话关闭时候这个进程就结束了 试问如何才能forever一样,保持在后台运行?

node源码粗读(9):nextTick、timers API、MicroTasks注册到执行全阶段解读

$
0
0

本文主要介绍nextTick、timers API、MicroTasks几类任务是在什么时候注册和执行的,也会从node 的bootstrap到evnet-loop过程做一个简单的介绍

整体流程

在这里以下面这段代码为例子,画一下整体的运行流程:

setTimeout(() => console.log('timers API'), 10)
new Promise((resolve, reject) => resolve('microtask run')).then(arg => console.log(arg))
process.nextTick(() => console.log('run next tick'))
setImmediate(() => console.log('setImmediate API'))

issue20-1注意:

Environment::Start

在这里不做过多详细介绍了,之前的文章中介绍过很多。有一个知识点需要注意就是:Immediate是在这个阶段注册到uv_check_start中的。此Immediate其实是Environment::CheckImmediate函数,保证之后event-loop在运行的时候能在check阶段运行这个函数,进而触发immediate_callback_function实现对ImmediateList的调用。
至于idle部分,是为了在有ImmediateList的时候直接跳过poll阶段,毕竟poll是阻塞运行的。

bootstrap阶段

bootstrap阶段是node运行时候的构建阶段,也是最基础的阶段。bootstrap阶段会把整体的node架子搭起来(在这里不做详细介绍),之后运行业务代码。比如本文中的这个例子,上图中画的应该也比较清晰了,顺序执行。唯一的区别是:在执行不同API的时候,callback的去向是不一致的。从上图中也能看出来,这几个API最终的去向分别是:TimersList、microTask、immediateQueue、nextTickQueue。
其中,setTimeout在注册的时候会创建TimerWrap的实例,在创建实例的时候会初始化uv_timer,之后再通过TimerWrap.start启动uv_timer_start,开始监听,到时间触发运行回调函数: issue20-2 nextTick在注册之后且bootstrap构建结束后运行SetupNextTick函数,从而触发nextTick的运行,而nextTick在运行之后会触发runMicroTasks(),清空bootstrap阶段的microTask: issue20-3

event-loop阶段

在bootstrap之后便进入了event-loop。event-loop第一个阶段便是timers,在这里如果有到时间的Timer,便会触发OnTimeoutOnTimeout会触发InternalMakeCallback从而执行TimersList中的函数。而在执行完后还会触发InternalCallbackScope::Close,在这个函数中会触发nextTick,在触发nextTick后触发microTasks。setTimeout简易流程如下: issue20-4也正是InternalMakeCallbackInternalCallbackScope::Close使得libuv和v8紧紧的联系在了一起,一方面可以通过setTimeout来设置运行时间;另一方面又可以在setTimeout的回调中书写js代码。

原文地址:https://github.com/xtx1130/blog/issues/20,欢迎star和fork,如果有错误之处,还请在回复或者issue下面斧正。

by 小菜

Viewing all 14821 articles
Browse latest View live