導航:首頁 > 編程語言 > js如何使方法非同步調用

js如何使方法非同步調用

發布時間:2023-02-22 10:05:08

A. 如何在javascript中非同步調用一個函數

js">functionasync(){}
setTimeout(function(){
async();
},1000)

上面就是復非同步調用一個函制數。

js里的非同步函數有很多, 除了setTimeout和setInterval 還有bind以及很多事件綁定和監聽都屬於非同步操作。

B. js回調函數如何實現非同步,給一個例子

非同步處理不用阻塞來等待處理完成,而是允許後續操作,直至其程序將處理完成,並回調通知此函數

那麼在js中有如下幾種非同步方式:

示例1

varasync=function(callback){
//readdata
setTimeout(function(){
callback('data');
},1000);//1秒後回調
};
//使用
async(function(data){
alert(data);
});

示例2

varasync=function(callback){
varxhr=newXMLHttpRequest();
xhr.open('get','.',true);

xhr.onreadystatechange=function(){
callback(xhr.readyStatus);
};
xhr.send();
};

async(function(data){
alert(data);
});

示例3

varasync=function(callback){
varimg=newImage();
img.onload=img.onerror=function(){
callback(img);
};
img.src='x.jpg';
};
async(function(data){
alert(data);
});

C. 怎樣用JS實現非同步轉同步

源起

小飛是一名剛入行前端不久的新人,因為進到了某個大公司,儼然成為了學弟學妹眼中'大神',大家遇到js問題都喜歡問他,這不,此時他的qq彈出了這樣一條消息

"hi,大神在嗎?我有個問題想問,現在我們的代碼裡面有這樣的東西,可是得不到正確的返回結果

1234567functiongetDataByAjax () {return$.ajax(...postParam)}vardata = getDataByAjax()if(data) {console.log(data.info)}

"哦,你這里是非同步調用,不能直接獲得返回值,你要把if語句寫到回調函數中",小飛不假思索的說到,對於一個『專業』的fe來說,這根本不是一個問題。
「可是我希望只是改造getDataByAjax這個方法,讓後面的代碼成立。」
「研究這個沒有意義,非同步是js的精髓,同步的話會阻塞js調用,超級慢的,但是你要一再堅持的話,用async:true就好了」
「不愧是大神,我回去立刻試一試,么么噠」

兩天後,她哭喪著臉登上了qq
「試了一下你的方法,但是根本行不通,哭~~」
「別急,我看看你這個postParam的參數行嗎」

123456{...dataType:'jsonp',async:true...}

"這是一個jsonp請求啊,老掉牙的東西了,,jsonp請求是沒有辦法同步的"
「我知道jsonp請求的原理是通過script標簽實現的,但是,你看,script也是支持同步的呀,你看tags/attscriptasync.asp」
「額,那可能是jquery沒有實現吧,哈哈」
「大神,你能幫我實現一個jsonp的同步調用方式嘛,拜託了(星星眼)」
雖然他有點奇怪jquery為什麼沒有實現,但是既然w3school的標准擺在那裡,碼兩行代碼又沒什麼,

loadJsonpSync = (url) => {varresult;window.callback1 = (data) => (result = data)lethead = window.document.getElementsByTagName('head')[0]letjs = window.document.createElement('script')js.setAttribute('type','text/javascript')js.setAttribute('async','sync')// 這句顯式聲明強調src不是按照非同步方式調用的js.setAttribute('src', url)head.appendChild(js)returnresult}

額,運行起來結果竟然是undefined!w3cshool的文檔竟然也不準,還權威呢,我看也不怎麼著,小飛暗自想到。

「剛才試了一下,w3school文檔上寫的有問題,這個非同步屬性根本就是錯的」
「可是我剛還試過一次這個,我確認是好的呀」

12<script src="loop50000 && put('frist').js"></script><script src="put('second').js"></script>

(有興趣的同學可以實現以下兩個js,並且加上async的標簽進行嘗試。)
「這個,我就搞不清楚了」,小飛訕訕的說到
對方已離線

抽象

關於這個問題,相信不只是小飛,很多人都難以解答。為什麼ajax可以做到同步,但jsonp不行,推廣到nodejs上,為什麼readFile也可以做到同步(readFileSync),但有的庫卻不行。
(至於script的async選項我們暫時避而不談,是因為現在的知識維度暫時還不夠,但是不要著急,下文中會給出明確的解釋)
現在,讓我們以計算機科學的角度抽象這個問題:

我們是否可以將非同步代碼轉化為同步代碼呢?(ASYNCCALL => SYNCCALL)

既然是抽象問題,那麼我們就可以不從工程角度/性能角度/實現語言等等等方面來看(同步比非同步效率低下),每增加一個維度,復雜程度將以幾何爆炸般增長下去。

首先,我們來明確一點,==在計算機科學領域==同步和非同步的定義

同步(英語:Synchronization),指對在一個系統中所發生的事件(event)之間進行協調,在時間上出現一致性與統一化的現象。在系統中進行同步,也被稱為及時(in time)、同步化的(synchronous、in sync)。--摘自網路
非同步的概念和同步相對。即時間不一致,不統一

明確了這一點,我們可以藉助甘特圖來表示同步和非同步

注意看我們標紅的地方,如果你完成了小測驗1,就會得到和這張圖一致的順序

==同步執行的代碼片段必然在非同步之前。==

所以,無論從理論還是實際出發,我們都不得不承認,在js中,把非同步方法改成同步方法這個命題是水月鏡花

哦對了,最後還需要解釋一下最開始我們埋下的坑, 為什麼jsonp中的async沒有生效,現在解釋起來真的是相當輕松,即document.appendChild的動作是交由dom渲染線程完成的,所謂的async阻塞的是dom的解析,而非js引擎的阻塞。實際上,在async獲取資源後,與js引擎的交互依舊是push taskQueue的動作,也就是我們所說的async call

推薦閱讀: 關於dom解析請大家參考webkit技術內幕第九章資源載入部分

峰迴路轉

相信很多新潮的同學已經開始運用切了async/await語法,在下面的語法中,getAjax1和console之間的具有同步的特性

1234asyncfunction() {vardata = await getAjax1()console.log(data)}

講完了event loop和非同步的本質,我們來重新審視一下async/await。
老天,這段代碼親手推翻了==同步執行的代碼片段必然在非同步之前。== 的黃金定律!
驚不驚喜,意不意外,這在我們的模型里如同三體里的質子一樣的存在。我們重新審視了一遍上面的模型,實在找不到漏洞,找不到任何可以推翻的點,所以真的必須承認,async/await絕對是一個超級神奇的魔法。
到這里來看我們不得不暫時放棄前面的推論,從async/await本身來看這個問題
相信很多人都會說,async/await是CO的語法糖,CO又是generator/promise的語法糖,好的,那我們不妨去掉這層語法糖,來看看這種代碼的本質, 關於CO,讀的人太多了,我實在不好老生常談,可以看看這篇文章,咱們就直接繞過去了,這里給出一個簡易的實現
/5800210.html

functionwrap(wait) {variteriter = wait()const f = () => {const { value } = iter.next()value && value.then(f)}f()}function*wait() {varp = () =>newPromise(resolve => {setTimeout(() => resolve(), 3000)})yieldp()console.log('unlock1')yieldp()console.log('unlock2')console.log('it's sync!!')}

終於,我們發現了問題的關鍵,如果單純的看wait生成器(注意,不是普通的函數),是不是覺得非常眼熟。這就是我們最開始提出的spinlock偽代碼!!!
這個已經被我們完完全全的否定過了,js不可能存在自旋鎖,事出反常必有妖,是的,yield和*就是表演async/await魔法的妖精。
generator和yield字面上含義。Gennerator叫做生成器,yield這塊ruby,python,js等各種語言界爭議很大,但是大多數人對於『讓權』這個概念是認同的(以前看到過maillist上面的爭論,但是具體的內容已經找不到了)

擴展閱讀---ruby元編程 閉包章節yield(ruby語義下的yield)

所謂讓權,是指cpu在執行時讓出使用權利,操作系統的角度來看就是『掛起』原語,在eventloop的語義下,似乎是暫存起當時正在執行的代碼塊(在我們的eventloop裡面對應runPart),然後順序的執行下一個程序塊。
我們可以修改eventloop來實現讓權機制

小測驗2 修改eventloop使之支持yield原語

至此,通過修改eventloop模型固然可以解決問題,但是,這並不能被稱之為魔法。

和諧共存的世界

實際上通過babel,我們可以輕松的降級使用yield,(在es5的世界使用讓權的概念!!)
看似不可能的事情,現在,讓我們撿起曾經論證過的
==同步執行的代碼片段必然在非同步之前。== 這個定理,在此基礎上進行進行逆否轉化

==在非同步代碼執行之後的代碼必然不是同步執行的(非同步的)。==

這是一個圈子裡人盡皆知的話,但直到現在他才變得有說服力(我們繞了一個好長的圈子)
現在,讓我們允許使用callback,不使用generator/yield的情況下完成一個wait generator相同的功能!!!

functionwait() {const p = () => ({value:newPromise(resolve => setTimeout(() => resolve(), 3000))})letstate = {next: () => {state.next = programPartreturnp()}}functionprogramPart() {console.log('unlocked1')state.next = programPart2returnp()}functionprogramPart2() {console.log('unlocked2')console.log('it's sync!!')return{value: void 0}}returnstate}

太棒了,我們成功的完成了generator到function的轉化(雖然成本高昂),同時,這段代碼本身也解釋清楚了generator的本質,高階函數,片段生成器,或者直接叫做函數生成器!這和scip上的翻譯完全一致,同時擁有自己的狀態(有限狀態機)

推薦閱讀 計算機程序的構造和解釋 第一章generator部分
小測驗3 實際上我們提供的解決方式存在缺陷,請從作用域角度談談

其實,在不知不覺中,我們已經重新發明了計算機科學中大名鼎鼎的CPS變換
Continuation-passing_style

最後的最後,容我向大家介紹一下facebook的CPS自動變換工具--regenerator。他在我們的基礎上修正了作用域的缺陷,讓generator在es5的世界裡自然優雅。我們向facebook脫帽致敬!!egenerator

後記

同步非同步 可以說是整個圈子裡面最喜歡談論的問題,但是,談來談去,似乎絕大多數變成了所謂的『約定俗稱』,大家意味追求新技術的同時,卻並不關心新技術是如何在老技術上傳承發展的,知其然而不知其所以然,人雲亦雲的寫著似是而非的js。

==技術,不應該浮躁==

PS: 最大的功勞不是CO,也不是babel。regenerator的出現比babel早幾個月,而且最初的實現是基於esprima/recast的,關於resprima/recast,國內似乎了解的並不多,其實在babel剛剛誕生之際, esprima/esprima-fb/acron 以及recast/jstransfrom/babel-generator幾大族系圍繞著react產生過一場激烈的斗爭,或許將來的某一天,我會再從實現細節上談一談為什麼babel笑到了最後~~~~

D. js可以非同步調用後台java方法嗎

一、為Test寫一個方法,不妨為dataToString(),把字元串數組變成一個字元串,格式為「
["A","B","C"]
但要注意字元中版A中可能會含有雙引號,權所以需要替換"為"
二、在前台JSP頁面中輸出一段這樣的語句:
<script>
var str = "<%=Test.toDataString()%>";
var arr = (str);
window.onload = function(){
for(var i=0;i<arr.length;i++){
//to do something
}
}
</script>
另一種方法就是在window.onload中用AJAX去取。利用AJAX必須寫servlet。因為前面一種方法的jsp和servlet是等同的。
js方法中調用java的參數
<input type="image"
src="../../images/icons/setParmeter.jpg" onclick="Block(<%=flag%>)" />
<input type="text" id="isparemeter" value="<%=flag%>"/>

E. 站ajax載入,非同步的頁面有js,應該如何讓它執行。

1、AJAX提交,非同步頁面JS是可以執行的,
2、只不過對於這種頁面既有HTML又有JS的解釋性內語言,執行是講究先容後順序的
3、除非就是給JS綁定事件如引入jquery文件後$(function(){});其中綁定事件代碼部分要寫到{}裡面
4、或者JS操作的是非同步頁面標簽,可以選擇把JS代碼部分放到HTML代碼部分後面

F. javascript中非同步操作的異常怎麼處理

一、JavaScript非同步編程的兩個核心難點
非同步I/O、事件驅動使得單線程的JavaScript得以在不阻塞UI的情況下執行網路、文件訪問功能,且使之在後端實現了較高的性能。然而非同步風格也引來了一些麻煩,其中比較核心的問題是:
1、函數嵌套過深
JavaScript的非同步調用基於回調函數,當多個非同步事務多級依賴時,回調函數會形成多級的嵌套,代碼變成

金字塔型結構。這不僅使得代碼變難看難懂,更使得調試、重構的過程充滿風險。
2、異常處理
回調嵌套不僅僅是使代碼變得雜亂,也使得錯誤處理更復雜。這里主要講講異常處理。
二、異常處理
像很多時髦的語言一樣,JavaScript 也允許拋出異常,隨後再用一個try/catch
語句塊捕獲。如果拋出的異常未被捕獲,大多數JavaScript環境都會提供一個有用的堆棧軌跡。舉個例子,下面這段代碼由於'{'為無效JSON
對象而拋出異常。
?

12345678

function JSONToObject(jsonStr) { return JSON.parse(jsonStr);}var obj = JSONToObject('{');//SyntaxError: Unexpected end of input//at Object.parse (native)//at JSONToObject (/AsyncJS/stackTrace.js:2:15)//at Object.<anonymous> (/AsyncJS/stackTrace.js:4:11)

堆棧軌跡不僅告訴我們哪裡拋出了錯誤,而且說明了最初出錯的地方:第4 行代碼。遺憾的是,自頂向下地跟蹤非同步錯誤起源並不都這么直截了當。
非同步編程中可能拋出錯誤的情況有兩種:回調函數錯誤、非同步函數錯誤。
1、回調函數錯誤
如果從非同步回調中拋出錯誤,會發生什麼事?讓我們先來做個測試。
?

1234567

setTimeout(function A() { setTimeout(function B() { setTimeout(function C() { throw new Error('Something terrible has happened!'); }, 0); }, 0);}, 0);

上述應用的結果是一條極其簡短的堆棧軌跡。
?

12

Error: Something terrible has happened!at Timer.C (/AsyncJS/nestedErrors.js:4:13)

等等,A 和B 發生了什麼事?為什麼它們沒有出現在堆棧軌跡中?這是因為運行C 的時候,非同步函數的上下文已經不存在了,A 和B 並不在內存堆棧里。這3
個函數都是從事件隊列直接運行的。基於同樣的理由,利用try/catch
語句塊並不能捕獲從非同步回調中拋出的錯誤。另外回調函數中的return也失去了意義。
?

1234567

try { setTimeout(function() { throw new Error('Catch me if you can!'); }, 0);} catch (e) {console.error(e);}

看到這里的問題了嗎?這里的try/catch 語句塊只捕獲setTimeout函數自身內部發生的那些錯誤。因為setTimeout
非同步地運行其回調,所以即使延時設置為0,回調拋出的錯誤也會直接流向應用程序。
總的來說,取用非同步回調的函數即使包裝上try/catch 語句塊,也只是無用之舉。(特例是,該非同步函數確實是在同步地做某些事且容易出錯。例如,Node
的fs.watch(file,callback)就是這樣一個函數,它在目標文件不存在時會拋出一個錯誤。)正因為此,Node.js
中的回調幾乎總是接受一個錯誤作為其首個參數,這樣就允許回調自己來決定如何處理這個錯誤。
2、非同步函數錯誤
由於非同步函數是立刻返回的,非同步事務中發生的錯誤是無法通過try-catch來捕捉的,只能採用由調用方提供錯誤處理回調的方案來解決。
例如Node中常見的function (err, ...)
{...}回調函數,就是Node中處理錯誤的約定:即將錯誤作為回調函數的第一個實參返回。再比如HTML5中FileReader對象的onerror函數,會被用於處理非同步讀取文件過程中的錯誤。
舉個例子,下面這個Node 應用嘗試非同步地讀取一個文件,還負責記錄下任何錯誤(如「文件不存在」)。
?

1234567

var fs = require('fs'); fs.readFile('fhgwgdz.txt', function(err, data) { if (err) { return console.error(err); }; console.log(data.toString('utf8'));});

客戶端JavaScript 庫的一致性要稍微差些,不過最常見的模式是,針對成敗這兩種情形各規定一個單獨的回調。jQuery 的Ajax
方法就遵循了這個模式。
?

1234

$.get('/data', { success: successHandler, failure: failureHandler});

不管API 形態像什麼,始終要記住的是,只能在回調內部處理源於回調的非同步錯誤。
三、未捕獲異常的處理
如果是從回調中拋出異常的,則由那個調用了回調的人負責捕獲該異常。但如果異常從未被捕獲,又會怎麼樣?這時,不同的JavaScript環境有著不同的游戲規則……
1. 在瀏覽器環境中
現代瀏覽器會在開發人員控制台顯示那些未捕獲的異常,接著返回事件隊列。要想修改這種行為,可以給window.onerror
附加一個處理器。如果windows.onerror 處理器返回true,則能阻止瀏覽器的默認錯誤處理行為。
?

123

window.onerror = function(err) { return true; //徹底忽略所有錯誤};

在成品應用中, 會考慮某種JavaScript 錯誤處理服務, 譬如Errorception。Errorception
提供了一個現成的windows.onerror 處理器,它向應用伺服器報告所有未捕獲的異常,接著應用伺服器發送消息通知我們。
2. 在Node.js 環境中
在Node 環境中,window.onerror 的類似物就是process 對象的uncaughtException 事件。正常情況下,Node
應用會因未捕獲的異常而立即退出。但只要至少還有一個uncaughtException 事件處理
器,Node 應用就會直接返回事件隊列。
?

123

process.on('uncaughtException', function(err) { console.error(err); //避免了關停的命運!});

但是,自Node 0.8.4 起,uncaughtException 事件就被廢棄了。據其文檔所言,對異常處理而言,uncaughtException
是一種非常粗暴的機制,請勿使用uncaughtException,而應使用Domain 對象。
Domain 對象又是什麼?你可能會這樣問。Domain 對象是事件化對象,它將throw 轉化為'error'事件。下面是一個例子。
?

123456789

var myDomain = require('domain').create();myDomain.run(function() { setTimeout(function() { throw new Error('Listen to me!') }, 50);});myDomain.on('error', function(err) { console.log('Error ignored!');});

源於延時事件的throw 只是簡單地觸發了Domain 對象的錯誤處理器。
Error ignored!
很奇妙,是不是?Domain 對象讓throw
語句生動了很多。不管在瀏覽器端還是伺服器端,全局的異常處理器都應被視作最後一根救命稻草。請僅在調試時才使用它。
四、幾種解決方案
下面對幾種解決方案的討論主要集中於上面提到的兩個核心問題上,當然也會考慮其他方面的因素來評判其優缺點。
1、Async.js
首先是Node中非常著名的Async.js,這個庫能夠在Node中展露頭角,恐怕也得歸功於Node統一的錯誤處理約定。

而在前端,一開始並沒有形成這么統一的約定,因此使用Async.js的話可能需要對現有的庫進行封裝。
Async.js的其實就是給回調函數的幾種常見使用模式加了一層包裝。比如我們需要三個前後依賴的非同步操作,採用純回調函數寫法如下:
?

12345678910111213141516

asyncOpA(a, b, (err, result) => { if (err) { handleErrorA(err); } asyncOpB(c, result, (err, result) => { if (err) { handleErrorB(err); } asyncOpB(d, result, (err, result) => { if (err) { handlerErrorC(err); } finalOp(result); }); });});

如果我們採用async庫來做:
?async.waterfall([ (cb) => { asyncOpA(a, b, (err, result) => { cb(err, c, result); }); }, (c, lastResult, cb) => { asyncOpB(c, lastResult, (err, result) => { cb(err, d, result); }) }, (d, lastResult, cb) => { asyncOpC(d, lastResult, (err, result) => { cb(err, result); }); }], (err, finalResult) => { if (err) { handlerError(err); } finalOp(finalResult);});

可以看到,回調函數由原來的橫向發展轉變為縱向發展,同時錯誤被統一傳遞到最後的處理函數中。

其原理是,將函數數組中的後一個函數包裝後作為前一個函數的末參數cb傳入,同時要求:
每一個函數都應當執行其cb參數;cb的第一個參數用來傳遞錯誤。我們可以自己寫一個async.waterfall的實現:
?let async = { waterfall: (methods, finalCb = _emptyFunction) => { if (!_isArray(methods)) { return finalCb(new Error('First argument to waterfall must be an array of functions')); } if (!methods.length) { return finalCb(); } function wrap(n) { if (n === methods.length) { return finalCb; } return function (err, ...args) { if (err) { return finalCb(err); } methods[n](...args, wrap(n + 1)); } } wrap(0)(false); }};

Async.js還有series/parallel/whilst等多種流程式控制制方法,來實現常見的非同步協作。
Async.js的問題:
在外在上依然沒有擺脫回調函數,只是將其從橫向發展變為縱向,還是需要程序員熟練非同步回調風格。

錯誤處理上仍然沒有利用上try-catch和throw,依賴於「回調函數的第一個參數用來傳遞錯誤」這樣的一個約定。
2、Promise方案
ES6的Promise來源於Promise/A+。使用Promise來進行非同步流程式控制制,有幾個需要注意的問題,

把前面提到的功能用Promise來實現,需要先包裝非同步函數,使之能返回一個Promise:
?

12345678910

function toPromiseStyle(fn) { return (...args) => { return new Promise((resolve, reject) => { fn(...args, (err, result) => { if (err) reject(err); resolve(result); }) }); };}

這個函數可以把符合下述規則的非同步函數轉換為返回Promise的函數:
回調函數的第一個參數用於傳遞錯誤,第二個參數用於傳遞正常的結果。接著就可以進行操作了:
?

123456789101112131415

let [opA, opB, opC] = [asyncOpA, asyncOpB, asyncOpC].map((fn) => toPromiseStyle(fn)); opA(a, b) .then((res) => { return opB(c, res); }) .then((res) => { return opC(d, res); }) .then((res) => { return finalOp(res); }) .catch((err) => { handleError(err); });

通過Promise,原來明顯的非同步回調函數風格顯得更像同步編程風格,我們只需要使用then方法將結果傳遞下去即可,同時return也有了相應的意義:

在每一個then的onFullfilled函數(以及onRejected)里的return,都會為下一個then的onFullfilled函數(以及onRejected)的參數設定好值。
如此一來,return、try-catch/throw都可以使用了,但catch是以方法的形式出現,還是不盡如人意。
3、Generator方案
ES6引入的Generator可以理解為可在運行中轉移控制權給其他代碼,並在需要的時候返回繼續執行的函數。利用Generator可以實現協程的功能。
將Generator與Promise結合,可以進一步將非同步代碼轉化為同步風格:
?

1234567891011

function* getResult() { let res, a, b, c, d; try { res = yield opA(a, b); res = yield opB(c, res); res = yield opC(d); return res; } catch (err) { return handleError(err); }}

然而我們還需要一個可以自動運行Generator的函數:
?

2324252627282930

function spawn(genF, ...args) { return new Promise((resolve, reject) => { let gen = genF(...args); function next(fn) { try { let r = fn(); if (r.done) { resolve(r.value); } Promise.resolve(r.value) .then((v) => { next(() => { return gen.next(v); }); }).catch((err) => { next(() => { return gen.throw(err); }) }); } catch (err) { reject(err); } } next(() => { return gen.next(undefined); }); });}

用這個函數來調用Generator即可:
?

1234567

spawn(getResult) .then((res) => { finalOp(res); }) .catch((err) => { handleFinalOpError(err); });

可見try-catch和return實際上已經以其原本面貌回到了代碼中,在代碼形式上也已經看不到非同步風格的痕跡。
類似的功能有co/task.js等庫實現。
4、ES7的async/await
ES7中將會引入async function和await關鍵字,利用這個功能,我們可以輕松寫出同步風格的代碼,

同時依然可以利用原有的非同步I/O機制。
採用async function,我們可以將之前的代碼寫成這樣:
?

12345678910111213

async function getResult() { let res, a, b, c, d; try { res = await opA(a, b); res = await opB(c, res); res = await opC(d); return res; } catch (err) { return handleError(err); }} getResult();

和Generator & Promise方案看起來沒有太大區別,只是關鍵字換了換。
實際上async
function就是對Generator方案的一個官方認可,將之作為語言內置功能。
async function的缺點:
await只能在async function內部使用,因此一旦你寫了幾個async function,或者使用了依賴於async
function的庫,那你很可能會需要更多的async function。
目前處於提案階段的async
function還沒有得到任何瀏覽器或Node.JS/io.js的支持。Babel轉碼器也需要打開實驗選項,並且對於不支持Generator的瀏覽器來說,還需要引進一層厚厚的regenerator
runtime,想在前端生產環境得到應用還需要時間。
以上就是本文的全部內容,希望對大家的學習有所幫助。

G. js如何非同步執行方法

functionmyThread(callback){

returnsetTimeout(1000*10,function(){

$("#div").append("<p>hello</p>");//10秒後在div中加一個行,然後在執行callback函數

callback();

});

}

用回調內函容數

functionA(fun){

vartemp=100;

temp=temp*temp;

window.setTimeout(function(){

fun(temp);

},0);

alert("a函數:"+temp);

}

functionB(r){

alert("b函數"+r);

}

A(B);//調用

H. js里怎麼非同步調用後台非靜態方法

既然是非同步,就不可能用for循環,因為for循環體中是沒有辦法暫停等待非同步調用的。應該用函數遞歸的方式循環

I. JS 怎麼讓整體的for同步執行而for中的非同步函數非同步執行

functionasync1(callback){
setTimeout(_=>{
console.log('async1:'+newDate().toTimeString());
callback();
},2000);
}

functionasync2(){
returnnewPromise(resolve=>{
setTimeout(_=>{
console.log('async2:'+newDate().toTimeString());
resolve();
},2000);
})
}

functionasync3(){
returnPromise.resolve().then(_=>console.log('async3:'+newDate().toTimeString()));
}

//將async1封裝為方式
functionasync1_promise(callback){
returnnewPromise((resolve,reject)=>{
try{
async1((...args)=>{
typeofcallback==='function'&&callback.apply(null,args);
resolve();
});
}catch(e){
reject(e);
}
});
}

functiontest1(){
//先執行4次async1,執行完上1個再執行下一個
//然後執行4次async2,執行完上1個再執行下一個
//再執行1次async3
async1_promise()
.then(_=>async1_promise())
.then(_=>async1_promise())
.then(_=>async1_promise())
.then(_=>async2())
.then(_=>async2())
.then(_=>async2())
.then(_=>async2())
.then(_=>async3());
}

functiontest2(){
//和test1相同,只是寫法簡化,如果要執行很多次可以這么寫
varstep=Promise.resolve();
for(leti=0;i++<4;step=step.then(_=>async1_promise()));
for(leti=0;i++<4;step=step.then(_=>async2()));
step.then(_=>async3());
}

functiontest3(){
//先執行4次async1,無需等待上1個執行完就執行下一個
//然後執行4次async2,無需等待上1個執行完就執行下一個
//再執行1次async3
Promise.all(Array.from(newArray(4),_=>async1_promise()))
.then(_=>Promise.all(Array.from(newArray(4),_=>async2())))
.then(_=>async3());
}

如果要測試,注意不要同時運行,需要單獨運行test1, test2, test3, 在瀏覽器控制台查看效果.

閱讀全文

與js如何使方法非同步調用相關的資料

熱點內容
dxf編程如何修刀 瀏覽:344
js音頻控制 瀏覽:112
蘋果6p微信發送語音會自己中斷 瀏覽:644
win10拷貝文件到u盤速度慢 瀏覽:396
怎麼把ps源文件字體改清楚 瀏覽:440
u盤如何恢復win10系統下載 瀏覽:153
完美世界100級升級攻略 瀏覽:67
安卓手機去除廣告軟體 瀏覽:529
水果禮品卡網站有哪些 瀏覽:272
愛譜數據線纜多少錢 瀏覽:165
word轉換成圖片格式 瀏覽:182
移動數據收費標準是多少 瀏覽:952
me525微信451去升級版 瀏覽:152
如何把壓縮文件變成永久文件 瀏覽:828
數據分片最大值多少 瀏覽:598
會玩app開完小號如何找回大號 瀏覽:939
html顯示flash代碼 瀏覽:651
while語句java 瀏覽:376
iphone鉻黃ps 瀏覽:529
linux掛載到已有分區 瀏覽:327

友情鏈接