導航:首頁 > 方法技巧 > vueasync方法如何被調用

vueasync方法如何被調用

發布時間:2022-08-05 23:15:58

㈠ vue實現路由跳轉的原理是什麼,是調用js底層什麼方法

前端路由是直接找到與地址匹配的一個組件或對象並將其渲染出來。改變瀏覽器地址而不向伺服器發出請求有兩種方式:
1. 在地址中加入#以欺騙瀏覽器,地址的改變是由於正在進行頁內導航
2. 使用H5的window.history功能,使用URL的Hash來模擬一個完整的URL。
當打包構建應用時,Javascript 包會變得非常大,影響頁面載入。如果我們能把不同路由對應的組件分割成不同的代碼塊,然後當路由被訪問的時候才載入對應組件,這樣就更加高效了。

目錄結構
先來看看整體的目錄結構

和流程相關的主要需要關注點的就是 components、history 目錄以及 create-matcher.js、create-route-map.js、index.js、install.js。下面就從 basic 應用入口開始來分析 vue-router 的整個流程。
import Vue from 'vue'
import VueRouter from 'vue-router'

// 1. 插件
// 安裝 <router-view> and <router-link> 組件
// 且給當前應用下所有的組件都注入 $router and $route 對象
Vue.use(VueRouter)

// 2. 定義各個路由下使用的組件,簡稱路由組件
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 3. 創建 VueRouter 實例 router
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/', component: Home },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
})

// 4. 創建 啟動應用
// 一定要確認注入了 router
// 在 <router-view> 中將會渲染路由組件
new Vue({
router,
template: ` <div id="app">
<h1>Basic</h1>
<ul>
<li><router-link to="/">/</router-link></li>
<li><router-link to="/foo">/foo</router-link></li>
<li><router-link to="/bar">/bar</router-link></li>
<router-link tag="li" to="/bar">/bar</router-link>
</ul>
<router-view class="view"></router-view>
</div>
`
}).$mount('#app')04142

作為插件
上邊代碼中關鍵的第 1 步,利用 Vue.js 提供的插件機制 .use(plugin) 來安裝 VueRouter,而這個插件機制則會調用該 plugin 對象的 install 方法(當然如果該 plugin 沒有該方法的話會把 plugin 自身作為函數來調用);下邊來看下 vue-router 這個插件具體的實現部分。
VueRouter 對象是在 src/index.js 中暴露出來的,這個對象有一個靜態的 install 方法:
/* @flow */
// 導入 install 模塊
import { install } from './install'// ...import { inBrowser, supportsHistory } from './util/dom'// ...export default class VueRouter {
// ...}

// 賦值 install
VueRouter.install = install

// 自動使用插件if (inBrowser && window.Vue) {
window.Vue.use(VueRouter)
}123456789101112131415161718

可以看到這是一個 Vue.js 插件的經典寫法,給插件對象增加 install 方法用來安裝插件具體邏輯,同時在最後判斷下如果是在瀏覽器環境且存在 window.Vue 的話就會自動使用插件。
install 在這里是一個單獨的模塊,繼續來看同級下的 src/install.js 的主要邏輯:
// router-view router-link 組件import View from './components/view'import Link from './components/link'// export 一個 Vue 引用export let _Vue// 安裝函數export function install (Vue) {
if (install.installed) return
install.installed = true

// 賦值私有 Vue 引用
_Vue = Vue // 注入 $router $route
Object.defineProperty(Vue.prototype, '$router', {
get () { return this.$root._router }
}) Object.defineProperty(Vue.prototype, '$route', {
get () { return this.$root._route }
}) // beforeCreate mixin
Vue.mixin({
beforeCreate () { // 判斷是否有 router
if (this.$options.router) { // 賦值 _router
this._router = this.$options.router // 初始化 init
this._router.init(this) // 定義響應式的 _route 對象
Vue.util.defineReactive(this, '_route', this._router.history.current)
}
}
}) // 注冊組件
Vue.component('router-view', View)
Vue.component('router-link', Link)// ...}0414243

這里就會有一些疑問了?
· 為啥要 export 一個 Vue 引用?
插件在打包的時候是肯定不希望把 vue 作為一個依賴包打進去的,但是呢又希望使用 Vue 對象本身的一些方法,此時就可以採用上邊類似的做法,在 install 的時候把這個變數賦值 Vue ,這樣就可以在其他地方使用 Vue 的一些方法而不必引入 vue 依賴包(前提是保證 install 後才會使用)。
· 通過給 Vue.prototype 定義 $router、$route 屬性就可以把他們注入到所有組件中嗎?
在 Vue.js 中所有的組件都是被擴展的 Vue 實例,也就意味著所有的組件都可以訪問到這個實例原型上定義的屬性。
beforeCreate mixin 這個在後邊創建 Vue 實例的時候再細說。
實例化 VueRouter
在入口文件中,首先要實例化一個 VueRouter ,然後將其傳入 Vue 實例的 options 中。現在繼續來看在 src/index.js 中暴露出來的 VueRouter 類:
// ...import { createMatcher } from './create-matcher'// ...export default class VueRouter {
// ...
constructor (options: RouterOptions = {}) {
this.app = null
this.options = options
this.beforeHooks = []
this.afterHooks = []
// 創建 match 匹配函數
this.match = createMatcher(options.routes || [])
// 根據 mode 實例化具體的 History
let mode = options.mode || 'hash'
this.fallback = mode === 'history' && !supportsHistory if (this.fallback) {
mode = 'hash'
} if (!inBrowser) {
mode = 'abstract'
}
this.mode = mode switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base) break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback) break
case 'abstract':
this.history = new AbstractHistory(this) break
default:
assert(false, `invalid mode: ${mode}`)
}
}
// ...}

里邊包含了重要的一步:創建 match 匹配函數。
match 匹配函數
匹配函數是由 src/create-matcher.js 中的 createMatcher 創建的:
/* @flow */

import Regexp from 'path-to-regexp'// ...import { createRouteMap } from './create-route-map'// ...export function createMatcher (routes: Array<RouteConfig>): Matcher {
// 創建路由 map
const { pathMap, nameMap } = createRouteMap(routes)
// 匹配函數 function match (
raw: RawLocation,
currentRoute?: Route,
redirectedFrom?: Location
): Route {
// ...
} function redirect (
record: RouteRecord,
location: Location
): Route {
// ...
} function alias (
record: RouteRecord,
location: Location,
matchAs: string
): Route {
// ...
} function _createRoute (
record: ?RouteRecord,
location: Location,
redirectedFrom?: Location
): Route { if (record && record.redirect) { return redirect(record, redirectedFrom || location)
} if (record && record.matchAs) { return alias(record, location, record.matchAs)
} return createRoute(record, location, redirectedFrom)
}
// 返回 return match
}
// ...04142434445464748495051

具體邏輯後續再具體分析,現在只需要理解為根據傳入的 routes 配置生成對應的路由 map,然後直接返回了 match 匹配函數。
繼續來看 src/create-route-map.js 中的 createRouteMap 函數:
/* @flow */import { assert, warn } from './util/warn'import { cleanPath } from './util/path'// 創建路由 mapexport function createRouteMap (routes: Array<RouteConfig>): {
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>
} { // path 路由 map
const pathMap: Dictionary<RouteRecord> = Object.create(null) // name 路由 map
const nameMap: Dictionary<RouteRecord> = Object.create(null) // 遍歷路由配置對象 增加 路由記錄
routes.forEach(route => {
addRouteRecord(pathMap, nameMap, route)
}) return {
pathMap,
nameMap
}
}// 增加 路由記錄 函數function addRouteRecord (
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>,
route: RouteConfig,
parent?: RouteRecord,
matchAs?: string
) {
// 獲取 path 、name
const { path, name } = route
assert(path != null, `"path" is required in a route configuration.`) // 路由記錄 對象
const record: RouteRecord = {
path: normalizePath(path, parent),
components: route.components || { default: route.component },
instances: {},
name, parent,
matchAs,
redirect: route.redirect,
beforeEnter: route.beforeEnter,
meta: route.meta || {}
} // 嵌套子路由 則遞歸增加 記錄
if (route.children) {// ...
route.children.forEach(child => {
addRouteRecord(pathMap, nameMap, child, record)
})
} // 處理別名 alias 邏輯 增加對應的 記錄
if (route.alias !== undefined) { if (Array.isArray(route.alias)) {
route.alias.forEach(alias => {
addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
})
} else {
addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
}
} // 更新 path map
pathMap[record.path] = record // 更新 name map
if (name) { if (!nameMap[name]) {
nameMap[name] = record
} else {
warn(false, `Duplicate named routes definition: { name: "${name}", path: "${record.path}" }`)
}
}
}function normalizePath (path: string, parent?: RouteRecord): string {
path = path.replace(/\/$/, '') if (path[0] === '/') return path if (parent == null) return path return cleanPath(`${parent.path}/${path}`)
}57677787980818283

可以看出主要做的事情就是根據用戶路由配置對象生成普通的根據 path 來對應的路由記錄以及根據 name 來對應的路由記錄的 map,方便後續匹配對應。
實例化 History
這也是很重要的一步,所有的 History 類都是在 src/history/ 目錄下,現在呢不需要關心具體的每種 History 的具體實現上差異,只需要知道他們都是繼承自 src/history/base.js 中的 History 類的:
/* @flow */// ...import { inBrowser } from '../util/dom'import { runQueue } from '../util/async'import { START, isSameRoute } from '../util/route'// 這里從之前分析過的 install.js 中 export _Vueimport { _Vue } from '../install'export class History {// ...
constructor (router: VueRouter, base: ?string) { this.router = router this.base = normalizeBase(base) // start with a route object that stands for "nowhere"
this.current = START this.pending = null
}// ...}// 得到 base 值function normalizeBase (base: ?string): string { if (!base) { if (inBrowser) { // respect <base> tag
const baseEl = document.querySelector('base') base = baseEl ? baseEl.getAttribute('href') : '/'
} else { base = '/'
}
} // make sure there's the starting slash
if (base.charAt(0) !== '/') { base = '/' + base

㈡ vue $emit 調用父組件非同步方法,執行完畢後再執行子組件的某方法,如何實現

//可以使用回調的方法

//父頁面
//父頁面調用組件的html中添加事件@test="test"
methods:{
test(data,cab){
setTimeout(()=>{
//這里使用定時器模擬執行完方法
console.log(data)//這是傳遞過來的參數用於處理
data++
cab(data)//將處理完成的數據返回回去
},2000)
}
}

//子頁面

this.$emit('tset',1,(res)=>{
console.log(res)//2秒後會執行這一句列印2

})
//我們也可以用Promise的方法代替回調
methods:{
test(data){
returnnewPromise((resolve)=>{
setTimeout(()=>{
//這里使用定時器模擬執行完方法
console.log(data)//這是傳遞過來的參數用於處理
data++
resolve(data)//將處理完成的數據返回回去
},2000)
})
}
}

//子頁面

constres=awaitthis.$emit('tset',1)
console.log(res)//2秒後會執行這一句

㈢ c#一個類方法怎麼調用async方法

如果要回去非同步方法獲取的結果:await 非同步方法();
如果不要回去非同步方法返回的結果,就正常調用:非同步方法();

㈣ 不加 await 調用 async 方法嗎

這樣的API被叫做同步或者阻塞。同步API易於理解和使用,不過在你的程序內部當前線程沒有反應時,API就無法控制你的代碼去做其它任務,因為它還不能傳遞結果。

㈤ c#中為什麼async方法里必須還要有await

首先一個被標記為async的方法,可以沒有await調用,只不過會有編譯警告。
這是很顯然的,不是說你把一個方法標記成async這個方法就成了非同步調用的方法了。async這個關鍵詞其實反而是可以省略的,這個關鍵詞存在的意義是為了向下兼容,為await提供上下文而已。

所以,一個async的方法裡面沒有await的調用,那等於是脫了褲子放屁,本質上只是把return xxx改成了retrurn Task.FromResult( xxx )而已,沒有任何變化。如果一個方法加上了async他就自動成為了非同步的調用,說明你連最根本的非同步是什麼都沒搞清楚。你所理解的那種所謂的非同步,直接用Task.Run就可以了

㈥ 如何在沒有 async 修飾的方法中使用非同步方法

使用非同步編程,可以避免性能瓶頸並增強應用程序的總體響應能力。 但是,編寫非同步應用程序的傳統技術可能比較復雜,使它們難以編寫、調試和維護。 C# 中的 async 和 await 關鍵字都是非同步編程的核心。 通過使用這兩個關鍵字,可以使用 .NET framework 或 Windows 運行時中的資源輕松創建非同步方法(幾乎與創建同步方法一樣輕松)。 通過使用被稱為非同步方法的 async 和 await 定義的非同步方法。 特徵: 方法簽名包含一個 Async 或 async 修飾符。 按照約定,非同步方法的名稱以「Async」後綴結尾。 返回類型為下列類型之一: 如果你的方法有操作數為 TResult 類型的返回語句,則為 Tasklt;TResultgt;。 如果你的方法沒有返回語句或具有沒有操作數的返回語句,則為 Task。 方法通常包含至少一個 await 表達式,該表達式標記一個點,在該點上,直到等待的非同步操作完成方法才能繼續。 同時,將方法掛起,並且控制項返回到方法的調用方。 本主題的下一節將解釋懸掛點發生的情況。 在非同步方法中,可使用提供的關鍵字和類型來指示需要完成的操作,且編譯器會完成其餘操作,其中包括持續跟蹤控制項以掛起方法返回等待點時發生的情況。 一些常規流程(例如,循環和異常處理)在傳統非同步代碼中處理起來可能很困難。 在非同步方法中,元素的編寫頻率與同步解決方案相同且此問題得到解決。

㈦ async用於函數調用介面只能適用於vue嗎,適用原生的js嗎

async/await 是ES2017加入的,只要你的開發和運行環境支持ES2017都可以使用

㈧ android AsyncTask的方法在哪幾個線程中調用

在開發Android移動客戶端的時候往往要使用多線程來進行操作,我們通常會將耗時的操作放在單獨的線程執行,避免其佔用主線程而給用戶帶來不好的用戶體驗。但是在子線程中無法去操作主線程(UI 線程),在子線程中操作UI線程會出現錯誤。因此android提供了一個類Handler來在子線程中來更新UI線程,用發消息的機制更新UI界面,呈現給用戶。這樣就解決了子線程更新UI的問題。但是費時的任務操作總會啟動一些匿名的子線程,太多的子線程給系統帶來巨大的負擔,隨之帶來一些性能問題。因此android提供了一個工具類AsyncTask,顧名思義非同步執行任務。這個AsyncTask生來就是處理一些後台的比較耗時的任務,給用戶帶來良好用戶體驗的,從編程的語法上顯得優雅了許多,不再需要子線程和Handler就可以完成非同步操作並且刷新用戶界面。
先大概認識下Android.os.AsyncTask類:
* android的類AsyncTask對線程間通訊進行了包裝,提供了簡易的編程方式來使後台線程和UI線程進行通訊:後台線程執行非同步任務,並把操作結果通知UI線程。
* AsyncTask是抽象類.AsyncTask定義了三種泛型類型 Params,Progress和Result。
* Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
* Progress 後台任務執行的百分比。
* Result 後台執行任務最終返回的結果,比如String,Integer等。
* AsyncTask的執行分為四個步驟,每一步都對應一個回調方法,開發者需要實現這些方法。
* 1) 繼承AsyncTask
* 2) 實現AsyncTask中定義的下面一個或幾個方法
* onPreExecute(), 該方法將在執行實際的後台操作前被UI 線程調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條,或者一些控制項的實例化,這個方法可以不用實現。
* doInBackground(Params...), 將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。這里將主要負責執行那些很耗時的後台處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
* onProgressUpdate(Progress...),在publishProgress方法被調用後,UI 線程將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
* onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法將被UI 線程調用,後台的計算結果將通過該方法傳遞到UI 線程,並且在界面上展示給用戶.
* onCancelled(),在用戶取消線程操作的時候調用。在主線程中調用onCancelled()的時候調用。
為了正確的使用AsyncTask類,以下是幾條必須遵守的准則:
1) Task的實例必須在UI 線程中創建
2) execute方法必須在UI 線程中調用
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法,需要在UI線程中實例化這個task來調用。
4) 該task只能被執行一次,否則多次調用時將會出現異常
doInBackground方法和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。

㈨ 如何正確理解.NET 4.5和C#5.0中的async/await非同步編程模式

這個await,其實只是把對老版本C#迭代器的慣用法官方化了。現在很多平台都因為一些原因不得不用舊版本的C#,比如unity,想非同步那隻能通過迭代器來做。

async、迭代器都是語法糖,編譯器會幫你實現成一個狀態機匿名類,實例裡面hold住一些臨時變數,記錄一下當前狀態。根據你寫的yield/await,把一個非同步方法拆成幾個同步block,根據一定規則定期的去MoveNext一下,Current是Task那我就根據你配置的線程上下文決定把這個Task跑在哪個線程上。

那麼用await修飾的非同步方法是在哪個線程中被調用的?為什麼上面這個事件處理方法不會阻塞GUI?
我還看到其它一些描述是說使用async/await非同步模式不會生成新的線程,那麼只在原來已有線程的基礎上面如何做到非同步運行?
題主這個例子這個方法就是在UI線程調用的,並且沒有ConfigureAwait(false),所以會在當前await時捕捉的UI線程上下文執行之後的同步block。
至於為什麼不會阻塞,可以簡單理解為執行了第一個block,碰到Delay(4000),給UI線程的定時器掛一個4000時間之後再調用下一個同步塊的回調。

看題主說的書名像是國產的書,這方面還是看《CLR via C#》或者《Concurrency in C# cookbook》比較好。

㈩ static async 方法怎麼調用

在即將到來的新的Windows Runtime中更根本地確定任何API都不會運行超過50ms的時間。需要更長時間的操作將會由'kick off this operation'API來代替,不等待運算結果就直接立刻返回。這樣做是因為Microsoft希望Windows8 Metro程序能夠在即時的觸控.

閱讀全文

與vueasync方法如何被調用相關的資料

熱點內容
汽車電路電壓降測量方法 瀏覽:450
邊際量和彈性的計算方法 瀏覽:435
手機玩游戲狀態欄設置方法 瀏覽:113
巫毒娃娃的使用方法 瀏覽:893
lamy鋼筆墨囊如何使用方法 瀏覽:836
浴霸安裝在塑料扣板的視頻方法 瀏覽:12
100種關燈方法視頻 瀏覽:448
立式注塑機原點解決方法 瀏覽:374
頸椎病引起手麻鍛煉方法都有哪些 瀏覽:110
折貓的方法圖解步驟 瀏覽:855
有什麼方法可以仿一個app 瀏覽:592
手機倚天賺10塊錢的方法 瀏覽:468
酒糟鼻有治療的方法嗎 瀏覽:107
電腦改成自動獲取的方法 瀏覽:132
怎麼治腳臭最簡單有效的方法 瀏覽:165
自製工具的方法和技巧 瀏覽:836
黃酒加什麼飲用方法 瀏覽:728
全站儀怎麼使用方法 瀏覽:237
天然氣自動上水器安裝方法 瀏覽:991
向大大護墊使用方法 瀏覽:625