亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript全棧開發

發布時間:2020-06-16 18:56:52 來源:PHP中文網 閱讀:973 作者:元一 欄目:web開發

JavaScript(簡稱“JS”) 是一種具有函數優先的輕量級,解釋型或即時編譯型的高級編程語言。雖然它是作為開發Web頁面的腳本語言而出名的,但是它也被用到了很多非瀏覽器環境中,JavaScript 基于原型編程、多范式的動態腳本語言,并且支持面向對象、命令式和聲明式(如函數式編程)風格。JavaScript是一種屬于網絡的高級腳本語言,已經被廣泛用于Web應用開發,常用來為網頁添加各式各樣的動態功能,為用戶提供更流暢美觀的瀏覽效果。通常JavaScript腳本是通過嵌入在HTML中來實現自身的功能的。 

CRD指的是Create、Read、Delete。針對的數據對象,就是一個Todo對象,看起來是這樣的:

{id:1,subject:"Loving"}

如果是多個數據對象,看起來是這樣的:

[
  {id:1,subject:"Loving"},
  {id:1,subject:"Writing"},
  {id:1,subject:"Preying"}
]

這個看起來很簡單平實的JS對象,會在一組組函數、模塊和對象之間流動,甚至跨越網絡邊界,從內存到硬盤。它會被存儲在Mongodb內,也會從Mongodb提取出來,在用戶界面、HTTP客戶端,HTTP服務器傳遞。

整個App看起來就是一臺機器,可以說代碼在運轉這個機器,但是也不妨說是數據在驅動這個它。

使用Vuejs腳手架,快速搭建Todo App界面

我們給自己命題,做一個TODO應用,它看起來是這樣的:

JavaScript全棧開發

用戶可以看到一個編輯框,和一個清單。

  1. 在編輯框內加入新的todo項目,按回車即可加入到列表
  2. 列表內每個項目有一個按鈕,點擊按鈕,可以刪除當前項目

環境要求

說起來搭建JS全棧開發環境,涉及到的東西真的不少。大的選擇是這樣的:

  1. 前端采用Vuejs
  2. 后端采用Nodejs
  3. 存儲使用Mongodb。

大的選擇定了,小的配套也就跟著來,前端配套的話需要一系列的技術,特別是前端,對應著Vuejs,配套管理路由、狀態、組件的都有相應的技術手段。自己搭配的話,還是非常麻煩的。

幸好Vuejs還有一個前端腳手架工具vue-cli,它可以把以上的組件整合起來到一個工程內。一個最為基礎的vue-cli工程腳手架的創建,現在得需要160M左右的空間占用。在我的電腦和網絡情況下,需要2分半的時間才會完成。

前端 Vuejs

  1. vue-router,前端路由管理
  2. vuex,前端數據管理,專業一點的說法,就是狀態管理,這些數據,可能是屬性,數組,對象等等,可以跨組件訪問,而不像是data函數那樣提供的數據只能被本組件訪問,可以想到,稍微大一點的前端工程都必須前端狀態管理的。
  3. axios,前端HTTP訪問,以promise的形式,封裝了類似fetch,AJAX的能力
  4. buefy,前端微型框架,可以使用自定義標簽使用自定義組件,并且CSS框架為Bulma
  5. Bulma,盡管使用了微框架,只是讓對CSS framework的了解降到最低,但是不是說就不需要了解了。還是得學習的。Bulma相對于老牌的Bootstrap,是不需要依賴于JS框架,也沒有任何JS代碼,因此可以和任何一框架很好的結合,比如這里的Vuejs。這就是我選擇它的原因

后端 cli-service

為了給前端開發提供工具鏈和開發便利性,我們常常需要webpack&babel。有了它們,就可以使用ES6的語法,以及代碼更新后自動刷新等。這些都是非常便利的特性,用了就離不開的。有了vue-cli,對webpack&babel的了解可以降到最低,但是也不能不學,稍微需要一些定制的配置,也是必須要掌握的,起碼得知道如何啟動一個開發服務器,已經發布build,還有把前端服務經過proxyChain跳轉到后端服務去等等。所幸是在這個教程內,你不需要學習太多就可以把案例跑起來。

App Server + Mongodb

接下來看后端,一般習慣就是使用Nodejs+Express.js的搭配。這個沒有多少說的,都是老東西了。為了訪問Mongodb,也需要一套框架,基于Callback的,或者基于Promise+Await+Async的,也是需要選擇的。

為了便于理解,我會用一個最小的案例完成整個開發過程,就是案例在現實中并不存在,但是也是有用的,就是你可以當它們是模板,直接拷貝代碼,然后填充你的內容。天下代碼一大抄嘛,沒有什么不對的,畢竟這些寫代碼是最快的。這個案例的數據模型就是對一個{id,name}的對象進行CRD(創建刪除列表)。

安裝運行環境

安裝環境相對簡單,特別是如果使用Mac OS X的話。有一些工具鏈可以幫助快速搭建環境。當然Windows也并不多麻煩就是了,它常常提供的是一個安裝程序,大部分時間,你需要的就是點擊下一步。

這里以MAC為例,講解安裝。

mongodb

安裝和運行Mongodb Daemon:

brew install mongodb
mongodb

訪問驗證,首先執行Mongodb Shell:

mongo

輸入命令,查詢數據庫清單:

> show dbs
local           0.000GB

能夠看到這些信息,說明mongodb安裝成功。

Node.js

安裝并驗證:

$brew install nodejs
$node -v
10.7.0

能夠看到這些信息,說明Node.js安裝成功。

開始前端編碼

安裝編碼環境

首先安裝vue-cli,方法和一般的NPM模塊一樣的,我們安裝的版本是3.0:

npm i @vue/cli

查看版本:

vue -V
3.0.0

看到如下信息,說明成功。然后創建App的腳手架代碼:

vue create todoapp

注意,在此創建過程中,命令行會指示你做出選擇,我們會選擇Manual select feature,然后選擇router和vuex,其他不選。然后并執行此代碼:

cd todoapp
npm run serve

可以在瀏覽器中訪問localhost:8080看到Vue的啟動畫面。說明創建腳手架成功。

此時,vue-cli已經幫助安裝了vuex和router的模塊依賴。本節一次性的安裝全部剩余的全部NPM依賴,免得以后用一個安裝一個,麻煩而且啰嗦。

  npm install buefy --save
npm install axios --save

buefy是一個基于Bulma的Vuejs用戶界面組件庫。這次的UI的CSS方案,使用Bulma,Vuejs如果想要以定制組件的形式去使用它的話,那么需要安裝Buefy模塊。實際上,我研究過Bulma和 Bootstrap,還寫了一本免費的電子書,我覺得Bulma相對于Bootstrap的優勢在于1.不依賴任何JS框架2.用戶接口設計更加簡明。這就是我現在選擇使用Bulma的原因。

Axios是一個封裝了HTTPClient的庫,提供了promise接口。我們使用它訪問后端的HTTP Server的數據。之前提到的數據對象,就是由Axios提取到客戶端,也會是通過Axios把數據對象提交到服務器的。

前端編碼

首先,我們從狀態開始。我們之前提到的Vuex,是Vuejs管理狀態的官方插件。所謂的狀態,就是應用程序的數據對象們。也就是我們提到的Todo對象和Todo對象集合。我們在App用戶界面上看到的很多數據都是來自于狀態對象。狀態對象在src/store.js。不僅僅是的應用狀態信息,還有和對這些的操作函數。既然需要一個todo項目清單,因此應該加入如下代碼:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const defaultTodo = [
      {id:1,subject:'Eating'},
      {id:2,subject:'Loving'},
      {id:3,subject:'Preying'},
    ]
function indexById(todos,id){
  for (var i = 0; i < todos.length; i++) {
    if (id == todos[i].id)
      return i
  }
  return -1
}
import axios from 'axios'
export default new Vuex.Store({
  state: {
    msg:'Todo App',
    todos:defaultTodo
  },
  mutations: {
    add(state,subject){
      var todo = {id:subject,subject:subject}
      state.todos.push(todo)
    },
    remove(state,id){
      state.todos.splice(indexById(state.todos,id),1)
    },
    reload(state){
      state.todos = defaultTodo
    }
  },
  actions: {
  add: (context, link) => {
      context.commit("add", link)
    },
    remove: (context, link) => {
      context.commit("remove", link)
    },
    reload: (context) => {
      context.commit("reload")
    }
  }
})

其中的state.todos屬性,就是我們的主要的數據對象了。state.msg這是提供了一個App的標題字符串。mutations屬性內是對數據修改提供的方法,比如

  1. 我們需要添加一個todo,使用add()方法,相應的
  2. 刪除一個todo,使用remove()方法
  3. 刷新一個todo列表,就會使用load()方法

有時候,對數據的修改可能是比較消耗時間的,因此為了避免阻塞客戶端的主線程,這個對象也提供了異步的方法,actions對象內就是對應修改操作的異步方法,這里的方法功能上和mutations一致,但是是異步的。Vuex提供了類似:

context.commit()

的語法,提供和actions和mutations方法的對接。第一個參數是mutations的方法名稱,之后的參數最為mutations方法的參數傳遞給mutations方法。

特別說下,mutations內的add()方法,其中用戶界面會提供一個Todo.subject屬性,而ID是需要自動生成的,我們這里臨時使用subject的值作為id,就是一個偷懶,只要subject不要輸入重復,也暫時可以蒙混過關。因為知道本項目內的后臺存儲會采用Mongodb,在Mongodb內插入一個新的對象后,會自動生成一個ID,我們的Todo對象的id會采用這個ID。這里就沒有必要自己生成了。

在src/views/home.vue內,粘貼為如下代碼:

<template>
  <p class="home">
    <h2>{{msg}}</h2>
    <NewTodo></NewTodo>
    <TodoList></TodoList>
  </p>
</template>
<script>
import NewTodo from '@/components/NewTodo.vue'
import TodoList from '@/components/TodoList.vue'
import {mapState,mapActions} from 'vuex'
export default {
  name: 'home',
  computed:mapState(['todos','msg']),
  components: {
    TodoList,NewTodo
  },
  data(){
      return{newtodo:''}
  },
  methods:{
      ...mapActions([
      'remove',
      'add'
    ]),
      add1:function(){
          this.add(this.newtodo)
          this.newtodo = ''
      }
  }
}
</script>

...mapState,mapActions的解說。

就是說,我們這個Todo App劃分為為兩個組件,其中一個組件負責顯示編輯框,并接受回車事件,把新的Todo項目加入到應用狀態內。另外一個組件負責顯示全部Todo項目,并接受刪除事件,刪除指定的Todo項目。它們分別是NewTodo組件和TodoList組件:

<NewTodo></NewTodo>
<TodoList></TodoList>

這兩個組件的代碼實現,分別在文件src/components/NewTodo.vuesrc/components/TodoList.vue內。NewTodo代碼:

<template>
  <p class="home">
    <form @submit.prevent="add1">
        <input type="text" name="newTodo" placeholder="new todo" v-model="newtodo">
    </form>
  </p>
</template>
<script>
import {mapState,mapActions} from 'vuex'
export default {
  name: 'newtodo',
  computed:mapState(['todos','msg']),
  data(){
      return{newtodo:''}
  },
  methods:{
      ...mapActions([
      'add'
    ]),
      add1:function(){
          this.add(this.newtodo)
          this.newtodo = ''
      }
  }
}
</script>

TodoList代碼:

<template>
  <p class="hello">
    <ul>
      <li v-for="(todo,index) in todos" v-bind:key="todo.id">
        {{todo.subject}}<button @click="remove(todo.id)" class="rm">remove</button>
      </li>
    </ul>
  </p>
</template>
<script>
import {mapState,mapActions} from 'vuex'
export default {
  name: 'todolist',
  computed:mapState(['todos','msg']),
  components: {
  },
  methods:{
    ...mapActions([
      'remove','reload'
    ])
  },
  mounted(){
    this.reload()
  }
}
</script>
<style scoped>
</style>

在src/main.js文件內,添加如下代碼,引入Buefy:

import Buefy from 'buefy'
import 'buefy/lib/buefy.css'
Vue.use(Buefy)

現在可以使用Buefy組件了。我們可以把NewTodo組件內的標準的input變成組件化的input,把標簽換成b-input即可。代碼如下:

<b-input type="text" name="newTodo" placeholder="new todo" v-model="newtodo"></b-input>

現在看瀏覽器,input變成了比較有吸引力的Bulma風格的控件了。訪問網絡使用axios。需要首先找到src/home.vue在代碼的開頭部分引用此庫:

import axios from 'axios'

在Vue單頁組件內使用此庫了。比如在src/home.vue內代碼對象中加入新方法:

mounted(){
  var url  = 'https://api.coindesk.com/v1/bpi/currentprice.json'
  axios ({
        url:url,
        method: 'get',
    })
    .then( res => {console.log(res.data.chartName)} )
    .catch( err => cosole.error(err))
}

我們來看看適應效果。啟動cli-service:

npm run serve

然后打開瀏覽器,輸入地址localhost:8080,如果可以在瀏覽器內看到我們期望的用戶界面,并且都可以看到console打印了Bitcoin,那么就說明用戶界面代碼和初步的訪問HTTP網絡的axios代碼以及狀態管理功能都是成功了的。

后端編碼

現在,我們已經可以看到UI了,但是用戶界面內的數據來自于客戶端,而不是來自于服務器。我們的數據當然應該來源于服務器的了。因此我們需要啟動給一個自己的服務器,這個服務器可以接受客戶在界面上錄入的新的Todo對象,也可以提供后端數據庫內的Todo清單。

為了測試的目的,常常需要準備一個todo應用的后臺JSON服務,可以通過HTTP方式,提供todo項目的增加刪除修改和查詢。

這樣的服務器,使用了nodejs作為服務器端,并且使用了兩個node模塊,可以使用npm安裝它們:

npm install express body-parser

body-parser是一個中間件,可以解析請求內容并把解析結果放到req.body屬性內。最常見的做法就是解析json內容。

代碼如下(文件名為:jsonserver.js):

  var express = require('express');
  var app = express();
  var path = require('path')
  var bodyParser = require('body-parser')
  app.use(bodyParser.json())
  var todos = []
  var public = path.join(__dirname, '/')
  app.use('/',express.static(public))
  const defaultTodo = [
    {id:1,subject:'Eating'},
    {id:2,subject:'Loving'},
    {id:3,subject:'Preying'},
  ]
  function rs(){
    todos = defaultTodo
  }
  function indexById(id){
    for (var i = 0; i < todos.length; i++) {
      if (id ==todos[i].id)return i
    }
    return -1
  }
  rs()
  app.delete('/api/todo/:id', function (req, res) {
    var userkey = +req.params.id
    todos.splice(indexById(userkey),1)
    res.end( JSON.stringify(todos));
    rs()
  })
  app.get('/api/todos', function (req, res) {
    res.end( JSON.stringify(todos));
  })
  app.post('/api/todo', function (req, res) {
    todos.push(req.body)
    res.end(JSON.stringify(todos))
    rs()
  })
  var server = app.listen(8081, function () {
    var host = server.address().address
    var port = server.address().port
    console.log("listening at http://%s:%s", host, port)
  })

可以使用命令執行:

node jsonserver.js

Curl命令驗證

可以通過curl命令驗證服務的有效性:

  1. GET操作

     $curl http://localhost:8081/todo/1
     $curl http://localhost:8081/todos
  2. DELETE操作

      $ curl -X "DELETE" http://localhost:8081/api/todo/1
  3. POST操作

    $curl -X POST  -H "Content-Type: application/json" -d '{"subject":"s4"}' http://localhost:8081/api/todo

前端HTML驗證

創建一個index.html文件,并放置到和jsonserver.js代碼同一目錄,代碼如下:

<a href='/todos'>todos</a>
<a href='/todo/1'>todo/1</a>
<button onclick='remove()'>remove 1</button>
<button onclick='create()'>create</button>
<script>
  function remove(){
    fetch (
      '/api/todo/1',
      {
        method: 'DELETE',
      }
    )
    .then( res => console.log(res.json()))
    .catch( err => cosole.error(err))
  }
  function create(){
    fetch (
      '/api/todo',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({id: "4", subject: "s4"})
      }
    )
    .then( res => console.log(res.json()))
    .catch( err => cosole.error(err))
  }
</script>

可以提供創建,刪除,列表的測試,其中部分結果在console內顯示。

說起來,JS訪問HTTP的庫真的是不少,這里 提到的庫都有9種。其中的fetch api使用起來非常的簡潔趁手,可是它不支持IE。如果你需要支持IE的話,使用Axios更好。這就是為什么Vuejs官方推薦Axios的原因吧:

The Fetch API is a powerful native API for these types of requests. You may have heard that one of the benefits of the Fetch API is that you don’t need to load an external resource in order to use it, which is true! Except… that it’s not fully supported yet, so you will still need to use a polyfill. There are also some gotchas when working with this API, which is why many prefer to use axios for now. This may very well change in the future though.

axios訪問方法

相比fetch,使用axios必須依賴于外部文件。為了方便,我們直接使用unpkg網站提供的庫文件。

axios的語法和fetch的大同小異,看著也是比較簡潔美觀的。以下代碼,把create和remove函數的內部實現換掉,其他不變。

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<a href='/todos'>todos</a>
<a href='/todo/1'>todo/1</a>
<button onclick='remove()'>remove 1</button>
<button onclick='create()'>create</button>
<script>
  function remove(){
    axios ({
        url:'/api/todo/1',
        method: 'DELETE',
    })
    .then( res => console.log(res.json()))
    .catch( err => cosole.error(err))
  }
  function create(){
    axios ({
        method: 'POST',
        url:'/api/todo',
        headers: {
          'Content-Type': 'application/json'
        },
        data: JSON.stringify({subject: "s4"})
    })
    .then( res => console.log(res.json()))
    .catch( err => cosole.error(err))
  }
</script>

現在,后端也是可以跑起來了的。

整合:前端后端

建立cli-service到App Server的通道

每次執行命令:npm run serve,都會啟動vue定制腳手架的服務器代碼,它會提供不少方便開發的特性。但是我希望一部分URL可以轉發到我自己的服務器內。比如把所有的/api打頭的URL全部轉過來。只要在工程根目錄內加入此文件vue.config.js,錄入如下內容:

module.exports = {
  devServer: {
    proxy: {
      "/api": {
        target: "http://localhost:8181",
        secure: false
      }
    }
  }
};

我們自己的測試服務器在這里:

var http = require('http');
http.createServer(function (req, res) {
  res.write('Hello World!'); 
  res.end(); 
}).listen(8181);

我們的定制服務器,就可以監聽8181的本地機器端口,等待客戶端的匹配的URL轉發過來,并轉發我們服務器的響應代碼到客戶端。

但是正常開發過程中,是需要自己的服務器端代碼的,如何在利用Vue腳手架服務器的方便性的基礎上,加入自己的代碼呢。做法是另外做一個定制的服務器,然后讓vue定制腳手架的服務器轉發URL到此服務器。

為了測試的目的,我們把函數mounted修改為:

mounted(){
  var url  = '/api/1'
  axios ({
        url:url,
        method: 'get',
    })
    .then( res => {console.log(res.data)} )
    .catch( err => console.error(err))
}

即可看到瀏覽器console內打印Hello World!

整合前端到后端

我們已經通過配置,要求cli-service轉移全部api打頭的URL到App Server。只要在工程根目錄內加入此文件vue.config.js,錄入如下內容:

module.exports = {
  devServer: {
    proxy: {
      "/api/*": {
        target: "http://localhost:8181/api",
        secure: false
      }
    }
  }
};

現在,我們可以修改前端的Axios使用代碼,分別替代前端代碼的數據裝入、數據刪除、數據添加的代碼,讓這些代碼可以支持網絡操作。為了避免網絡操作代碼和業務邏輯代碼混合在一起,我決定包裝三個網絡操作函數,并把它們放置到src/store.js文件內:

import axios from 'axios'
function httpadd(subject,cb){
  axios ({
        method: 'POST',
        url:'/api/todo',
        headers:[{'Content-Type':'application/json'}],
        data: {subject:subject}
      })
      .then( res => cb(res.data))
      .catch( err => console.error(err))
}
function httpremove(id,cb){
  axios ({
        url:'/api/todo/'+id,
        method: 'delete',
      })
      .then( res => {
          cb()
      })
      .catch( err => console.error(err))
}
function httpreload(cb){
  axios ({
        url:'/api/todos',
        method: 'get',
      })
      .then( res => {
          cb(res.data)
      })
      .catch( err => console.error(err))
}

分別完成添加、刪除、查找的任務,當完成工作后,都會調用一個callback函數,在此函數內,可以消費訪問網絡后得到的響應數據。

然后把文件內src/store.js的mutations對象改成如下代碼:

 mutations: {
  add(state,subject){
    httpadd(subject,function(todo){
      state.todos.push(todo)
    })
  },
  remove(state,id){
    httpremove(id,function(){
      state.todos.splice(indexById(state.todos,id),1)  
    })
  },
  reload(state){
    httpreload(function(todos){
      // console.log(todos)
      state.todos = todos
    })
    // state.todos = defaultTodo
  }
},

最后,在TodoList內加入一個新函數,并通過mapActions引入src/store.js的load()函數到當前對象內:

  methods:{
    ...mapActions([
      'remove','load'
    ])
  },
  mounted(){
    this.load()
  }

以便在啟動后調用this.load()裝入它。

整合:后端和數據庫

要完成后端到數據庫的整合,需要做如下的修改:

  1. 原本在后端App Server內Todo數據數組,現在應該從Mongodb獲得
  2. 原本在添加Todo對象的時候只是添加到AppServer對象內,現在需要同時寫入Mongodb
  3. 原本在刪除時只是從數組刪除,現在需要同時在Mongodb內刪除

因此,現在我們需要添加三個函數,分別做針對Mongodb的獲取清單、添加和刪除的工作:

var mongo = require('mongodb')
function insertDoc(subject,callback){
  const connectionString = 'mongodb://localhost:27017';
  (async () => {
      const client = await MongoClient.connect(connectionString,
          { useNewUrlParser: true });
      const dbo = client.db('todos');
      try {
         var res = await dbo.collection('todo').insertOne(
          {subject:subject})
         callback(undefined,res.insertedId)
      }
      catch(err){
        callback(err)
      }
      finally {
          client.close();
      }
  })().catch(err => console.error(err));
}
function deleteDoc(_id,callback){
  const MongoClient = mongo.MongoClient;
  const connectionString = 'mongodb://localhost:27017';
  (async () => {
      const client = await MongoClient.connect(connectionString,
          { useNewUrlParser: true });
      const dbo = client.db('todos');
      try {
              var myquery = {_id:new mongo.ObjectID(_id)}
              var r = await dbo.collection("todo").deleteMany(myquery)
        }
        catch(err){
        callback(err)
      }
      finally {
            client.close();
            callback()
        }
  })().catch(err => console.error(err));
}
function allDoc(callback){
  const MongoClient = mongo.MongoClient;
  const connectionString = 'mongodb://localhost:27017';
  (async () => {
      const client = await MongoClient.connect(connectionString,
          { useNewUrlParser: true });
      const dbo = client.db('todos');
      try {
             var r = await dbo.collection("todo").find().toArray()
             var ts = []
             for (var i = 0; i < r.length; i++) {
               ts.push({id:r[i]._id,subject:r[i].subject})
             }
             callback(undefined,ts)
        }
        catch(err){
        callback(err)
      }
      finally {
            client.close();
        }
  })().catch(err => console.error(err));
}

這三個函數的功能和使用方法如下:

  1. 函數allDoc會從Mongodb內獲取全部todo集合,并通過callback傳遞這個集合給調用者函數。
  2. 函數deleteDoc會從Mongodb內刪除指定id的todo條目,完成刪除后,通過callback通知調用者。
  3. 函數deleteDoc會向Mongodb內添加一個todo條目,完成添加后,通過callback通知調用者,并傳遞新的todo對象給調用者。

這里的代碼本身并不復雜,但是因為涉及到如何訪問Mongodb,因此涉及到比較多的概念,這里不做具體的解釋,你可以先把它們用起來。如果完成了本教程后,希望對Mongodb的訪問做具體了解的話,可以查看后文附錄的“Mongodb快速參考”。

并且和App Server對應的代碼接駁,把原來的路由代碼替換如下:

app.delete('/api/todo/:id', function (req, res) {
  var userkey = req.params.id
  deleteDoc(userkey,function(){
    todos.splice(indexById(userkey),1)
    res.end( JSON.stringify(todos));
  })
})
app.get('/api/todos', function (req, res) {
  allDoc(function(err,todos){
    res.end( JSON.stringify(todos));  
  })
})
app.post('/api/todo', function (req, res) {
  insertDoc(req.body.subject,function(err,_id){
    var obj ={id:_id,subject:req.body.subject}
  todos.push(obj)
  res.end(JSON.stringify(obj))
    rs()
  })
})

Mongodb快速參考

本文會把一個對象todo對象(有屬性{id,name})存儲到Mongodb,做查詢刪除的測試(Create Remove Delete = CRD)。這個測試包括使用Mongodb Shell,使用CallBack古典風格的訪問代碼,以及使用Await/Async的現代風格的代碼。完成這個這個驗證后,就可以掌握最初步的Mongodb了。

我使用的Nodejs是10.7 。操作系統環境為Mac OS X High Sierra。

準備環境

安裝和運行Mongodb Daemon

brew install mongodb
mongodb

訪問驗證

首先執行Mongodb Shell:

mongo

輸入命令,查詢數據庫清單:

> show dbs
local           0.000GB

創建一個數據庫

use todos

(若database不存在,則會創建一個,此時若不做任何操作直接退出,則MongoDB會刪除該數據庫)

db.todos.insert({id:1,name:"reco"})
db.todos.insert({id:2,name:"rita"})

查詢 :

db.todos.find()

{ "_id" : ObjectId("5b727c0846b6c71a98d3af52"), "id" : 1, "name" : "reco" }
{ "_id" : ObjectId("5b727c7046b6c71a98d3af53"), "id" : 2, "name" : "reta" }

刪除記錄:

db.todo.remove({id:1})

刪除數據庫

db.todo.drop()

使用nodejs方式訪問Mongodb

使用nodejs執行類似Shell對對象的CRD,代碼如下:

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/todos";
MongoClient.connect(url, function(err, db) {
  if (err) throw err;
  console.log("Database created!");
  var dbo = db.db("todos");
  // var myobj = { id: 1, name: "reco" };
  // dbo.collection("todo").insertOne(myobj, function(err, res) {
  //   if (err) throw err;
  //   console.log("1 document inserted");
  //   db.close();
  // });
   var myobj = [
    { id: 1, name: 'reco'},
    { id: 2, name: 'rita'},
  ];
  dbo.collection("todo").insertMany(myobj, function(err, res) {
    if (err) throw err;
    console.log("Number of documents inserted: " + res.insertedCount);
    dbo.collection("todo").find({}).toArray(function(err, result) {
      if (err) throw err;
      console.log(result);
        var myquery = { id: 1 };
      dbo.collection("todo").deleteMany(myquery, function(err, obj) {
        if (err) throw err;
        console.log("document deleted");
        db.close();
      });
    });    
  });
})

代碼非常簡單,無需更多解釋。此代碼使用了mongodb模塊,需要首先安裝:

npm init -y
npm i mongodb --save

然后使用node index.js運行即可看到效果:

Database created!
Number of documents inserted: 2
[ { _id: 5b72ab9e3245f169ef5f43d2, id: 1, name: 'reco' },
  { _id: 5b72ab9e3245f169ef5f43d3, id: 2, name: 'rita' } ]
document deleted

利用高級異步特性

使用Await/Async特性,可以有效的減少代碼中的回調地獄現象。同樣的功能,可以使用這樣的代碼:

const MongoClient = require('mongodb').MongoClient;
const connectionString = 'mongodb://localhost:27017';
(async () => {
    const client = await MongoClient.connect(connectionString,
        { useNewUrlParser: true });
    const dbo = client.db('todos');
    try {
       var res = await dbo.collection('todo').insertMany(
        [{id:1,name:"reco"}, {id:2,name:"rita"}]);
       console.log("Number of documents inserted: " + res.insertedCount);
       var r = await dbo.collection("todo").find().toArray()
       console.log(r);
       var myquery = { id: 1 };
     var r = await dbo.collection("todo").deleteMany(myquery)
     console.log("document deleted");
    }
    finally {
        client.close();
    }
})().catch(err => console.error(err));

執行此代碼,輸出如下:

Number of documents inserted: 2
[ { _id: 5b72ae8a1c674a6ac1c5aa6e, id: 1, name: 'reco' },
  { _id: 5b72ae8a1c674a6ac1c5aa6f, id: 2, name: 'rita' } ]
document deleted

以上就是直擊JavaScript全棧教程的詳細內容,更多請關注億速云其它相關文章!
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

拉萨市| 华阴市| 东乡族自治县| 双牌县| 浙江省| 镇雄县| 泾川县| 洛阳市| 芜湖市| 微博| 新田县| 珲春市| 阜城县| 平江县| 三江| 宁德市| 濮阳市| 德庆县| 儋州市| 平利县| 鲜城| 平罗县| 玛沁县| 疏勒县| 大英县| 会泽县| 定陶县| 尤溪县| 文安县| 偏关县| 视频| 龙山县| 大石桥市| 板桥市| 尉氏县| 吉木萨尔县| 武宣县| 海城市| 临澧县| 东丽区| 黑山县|