摘要:基數(shù),倒計時進入倒計時進入倒計時進入倒計時進入倒計時進入倒計時倒計數(shù)結(jié)束執(zhí)行完畢,結(jié)果為,準(zhǔn)備進入。
2018-12-21 更新
1、簡化調(diào)用方式,更貼近普通函數(shù)的風(fēng)格;
精簡版戳這里!
2018-12-05 更新
1、支持頭節(jié)點入?yún)ⅲ?br>2、簡化調(diào)用方式;
//源碼 function chainedFn(chain,firstFnArguments){ // 入?yún)?shù)據(jù)校驗 ... for(var i=0;i鏈條模板:
chainedFn([ {"fnName":方法名,"fnArg":實例化時的入?yún)ο?非必傳)}, {"fnName":方法名,"fnArg":實例化時的入?yún)ο?非必傳)}, {"fnName":方法名,"fnArg":實例化時的入?yún)ο?非必傳)} ],[頭節(jié)點入?yún)?,頭節(jié)點入?yún)?,頭節(jié)點入?yún)?...] );節(jié)點模板:
function 函數(shù)名(callback,鏈條上的【fnArg】(可選)){ //callback this.fnCont = function(...){ //如果是頭節(jié)點,則入?yún)?yīng)chainedFn的第二個參數(shù);否則等價于上一節(jié)點的【callback】 //TODO... if(typeof callback == "function"){ callback(...); // 等價于下一個節(jié)點的【fuCont】 } } }函數(shù)示例:
假設(shè)現(xiàn)在有3個需要同步執(zhí)行的函數(shù):FnA,F(xiàn)nB,F(xiàn)nC;
FnA的功能:將基數(shù)(入?yún)?),乘上乘積(入?yún)?),結(jié)果值和倒計時(入?yún)?)傳給FnB;
FnB的功能:進入倒計時,倒計時結(jié)束后,將入?yún)⒊松?,然后傳給fnC;
FnC的功能:將參數(shù)打印出來;// 組合鏈?zhǔn)疥P(guān)系 ... chainedFn([ {"fnName":FnA}, //規(guī)定初始值 {"fnName":FnB,"fnArg":"test"},//倒計時結(jié)束后,進行一些操作 {"fnName":FnC}//展示處理結(jié)果 ],[2,10,5] ); // FnA的功能:將入?yún)?乘上入?yún)?,然后執(zhí)行FnB,同時設(shè)置fnB的倒計時時間(入?yún)?)... function FnA(callback){ this.fnCont = function(base,multiplier,cDown){ console.log("【from FnA】基數(shù):" + base + ",乘積:" + multiplier + ",倒計時:" + cDown); var num = base * multiplier ; if(typeof callback == "function"){ console.log("【from FnA】執(zhí)行完畢,結(jié)果為:" + num + ",準(zhǔn)備進入FnB。"); callback(num,cDown); // 等價于【FnB】的fuCont } } } // FnB的功能:倒計時結(jié)束后,將入?yún)⒊松? ... function FnB(callback,fnArg){ this.fnCont = function(base,cDown){ alert(fnArg); console.log("【from FnB】基數(shù):" + base + ",倒計時:" + cDown); var countDown = cDown; var tTout = setInterval(function(){ console.log("【from FnB】進入倒計時 -> " + --countDown + "s"); if(countDown <= 0){ console.log("【from FnB】倒計數(shù)結(jié)束"); countDown = -1; clearTimeout(tTout); var num = base * 5; if(typeof callback == "function"){ console.log("【from FnB】執(zhí)行完畢,結(jié)果為:" + num + ",準(zhǔn)備進入FnC。"); callback(num);// 等價于【FnC】的fuCont } } },1000); } }; // 將參數(shù)打印出來 ... function FnC(callback){ this.fnCont = function(tArg){ console.log("【from FnC】計算結(jié)果為:" + tArg); if(typeof callback == "function"){ callback(); } } };執(zhí)行結(jié)果:
【from FnA】基數(shù):2,乘積:10,倒計時:5 【from FnA】執(zhí)行完畢,結(jié)果為:20,準(zhǔn)備進入FnB。 【from FnB】基數(shù):20,倒計時:5 【from FnB】進入倒計時 -> 4s 【from FnB】進入倒計時 -> 3s 【from FnB】進入倒計時 -> 2s 【from FnB】進入倒計時 -> 1s 【from FnB】進入倒計時 -> 0s 【from FnB】倒計數(shù)結(jié)束 【from FnB】執(zhí)行完畢,結(jié)果為:100,準(zhǔn)備進入FnC。 【from FnC】計算結(jié)果為:100此時突然新增一個需求:在FnA中指定一個值B,內(nèi)容FnC輸出值A(chǔ)不可大于B:如果A超過B則取B,否則取A:
FnA增加指定參數(shù)(maxNum),并傳出:
function FnA(callback){ this.fnCont = function(base,multiplier,cDown,maxNum){ console.log("【from FnA】基數(shù):" + base + ",乘積:" + multiplier + ",倒計時:" + cDown); var num = base * multiplier ; if(typeof callback == "function"){ console.log("【from FnA】執(zhí)行完畢,結(jié)果為:" + num + ",準(zhǔn)備進入下一節(jié)點"); callback(num,cDown,maxNum); // 等價于【FnB】的fuCont } } }FnB原封不動將值傳出:
function FnB(callback){ this.fnCont = function(base,cDown,maxNum){ console.log("【from FnB】基數(shù):" + base + ",倒計時:" + cDown); var countDown = cDown; var tTout = setInterval(function(){ console.log("from FnB:進入倒計時 -> " + --countDown + "s"); if(countDown <= 0){ console.log("【from FnB】倒計數(shù)結(jié)束"); countDown = -1; clearTimeout(tTout); var num = base * 5; if(typeof callback == "function"){ console.log("【from FnB】執(zhí)行完畢,結(jié)果為:" + num + ",準(zhǔn)備進入下一節(jié)點"); callback(num,maxNum);// 等價于【FnC】的fuCont } } },1000); } };新增一個方法(FnD),此函接受兩個入?yún),B。如果A小于B,則返回A,否則返回B:
function FnD(callback){ this.fnCont = function(num,max){ var tmpNum = num; var maxNum = max; if(tmpNum > maxNum){ tmpNum = maxNum; console.log("【from FnD】計算結(jié)果為:" + tArg); } if(typeof callback == "function"){ callback(tmpNum); } } };調(diào)整鏈?zhǔn)浇Y(jié)構(gòu)(指定最大值,增加FnD):
// 組合鏈?zhǔn)疥P(guān)系 ... chainedFn([ {"fnName":FnA},//規(guī)定初始值 {"fnName":FnB},//倒計時結(jié)束后,進行一些操作 {"fnName":FnD},//最大值限制 {"fnName":FnC} //展示處理結(jié)果 ],[2,10,3,50] );輸出結(jié)果:
【from FnA】基數(shù):2,乘積:10,倒計時:3 【from FnA】執(zhí)行完畢,結(jié)果為:20,準(zhǔn)備進入下一節(jié)點 【from FnB】基數(shù):20,倒計時:3 【from FnB】進入倒計時 -> 2s 【from FnB】進入倒計時 -> 1s 【from FnB】進入倒計時 -> 0s 【from FnB】倒計數(shù)結(jié)束 【from FnB】執(zhí)行完畢,結(jié)果為:100,準(zhǔn)備進入下一節(jié)點 【from FnD】值(100)超出限制,取限制值:50 【from FnC】計算結(jié)果為:50聊一下背景
最近在開發(fā)項目的時候,因為需要數(shù)據(jù)同步處理,所以會遇到很多涉及到函數(shù)回調(diào)的地方。最多的達到了7個!不管是自己擼代碼,還是維護代碼,基本都是一項很煩心的事,特別要改原先其他同事寫的邏輯,我寧愿重新寫。代碼都是這樣的:
a(xx,function(){ b(xx,function(){ c(xx,function(){ ..... }); }); });又或者這樣的:
function a(xx){ //..... b(); } function b(xx){ //..... c(); } ......故,抽了點時間寫了一個:以鏈?zhǔn)秸{(diào)用的形式用來處理需要回調(diào)的函數(shù)。
源碼:
/** *鏈?zhǔn)交卣{(diào) **/ function chainedFn(chain){ // 入?yún)?shù)據(jù)校驗 ... for(var i=0;i鏈條模板:
chainedFn([ {"fnName":方法名A,"fnArg":實例化時的入?yún)ο?非必傳)}, {"fnName":方法名B,"fnArg":實例化時的入?yún)ο?非必傳)}, {"fnName":方法名C,"fnArg":實例化時的入?yún)ο?非必傳)} ]); 說明:chainedFn的入?yún)⑹荍SON數(shù)組,【方法名名】需存在,且符合“對象模版”;【實例化時的入?yún)ⅰ繀?shù)可無;方法模版:
function **方法名**(**實例化參數(shù)**,callback){ this.fnCont = function(tArg1,tArg2...){ //fnCont:函數(shù)主體(函數(shù)名不可變),tArg:被回調(diào)的入?yún)?鏈條上一節(jié)的入?yún)? // 函數(shù)功能代碼 ... if(typeof callback == "function"){ callback(tArg1,tArg2...);//回調(diào)的入?yún)?鏈條下一節(jié)的入?yún)? } } }; 說明:【實例化參數(shù)】可為空;【fnCont】為函數(shù)主體,函數(shù)名不可修改;當(dāng)前一節(jié)【fnCont】等于上一節(jié)的【callback】即: A.callback() === B.fnCont() B.callback() === C.fnCont()鏈?zhǔn)秸{(diào)用回調(diào)函數(shù)都做了什么?
1、依照入?yún)⒅械南群箜樞?,動態(tài)組合了回調(diào)函數(shù);
2、將當(dāng)前的【callback】和下一個對象的【fnCont】進行映射綁定;使用過程應(yīng)注意什么?
1、根據(jù)實際情況調(diào)整回調(diào)順序,或者增加方法;
2、每一節(jié)的callback即上下一節(jié)的fnCont;函數(shù)示例:
假設(shè)現(xiàn)在有3個需要同步執(zhí)行的函數(shù):FnA,F(xiàn)nB,F(xiàn)nC;
FnA的功能:將入?yún)⒊松?0,然后傳給fnB,同時規(guī)定fnB的倒計時時間;
FnB的功能:進入倒計時,倒計時結(jié)束后,將入?yún)⒊松?,然后傳給fnC;
FnC的功能:將參數(shù)打印出來;// FnA的功能:將入?yún)⒊松?0,然后執(zhí)行FnB,同時設(shè)置fnB的倒計時時間(10s)... function FnA(arg,callback){ this.fnCont = function(){ var num = arg * 10 ; if(typeof callback == "function"){ callback(num,10); // 等價于【FnB】的fuCont } } } // FnB的功能:倒計時結(jié)束后,將入?yún)⒊松?,然后執(zhí)行FnC ... function FnB(arg,callback){ this.fnCont = function(tArg,cDown){ var num = tArg * 5; var countDown = cDown; var tTout = setInterval(function(){ console.log("from FnB:進入倒計時 -> " + --countDown + "s"); if(countDown <= 0){ console.log("from FnB:倒計數(shù)結(jié)束"); countDown = -1; clearTimeout(tTout); if(typeof callback == "function"){ console.log("from FnB:執(zhí)行回調(diào)函數(shù)"); callback(num);// 等價于【FnC】的fuCont } } },1000); } }; // 將參數(shù)打印出來 ... function FnC(arg,callback){ this.fnCont = function(tArg,awr){ console.log("from FnC:入?yún)⒌闹凳? + tArg); if(typeof callback == "function"){ callback(); } } }; // 組合鏈?zhǔn)疥P(guān)系 ... chainedFn([ {"fnName":FnA,"fnArg":2}, //規(guī)定初始值 {"fnName":FnB},//倒計時結(jié)束后,進行一些操作 {"fnName":FnC},//展示處理結(jié)果 ]);執(zhí)行結(jié)果:
from FnA:入?yún)⒌闹凳?2 userCenter.js?v=undefined:63 from FnB:進入倒計時 -> 10s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 9s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 8s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 7s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 6s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 5s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 4s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 3s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 2s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 1s userCenter.js?v=undefined:65 from FnB:進入倒計時 -> 0s userCenter.js?v=undefined:67 from FnB:倒計數(shù)結(jié)束 userCenter.js?v=undefined:82 from FnC:入?yún)⒌闹凳?00
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/88571.html
摘要:回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因為事件沒有被觸發(fā)或者條件不滿足。同步方式請求異步同步請求當(dāng)請求開始發(fā)送時,瀏覽器事件線程通知主線程,讓線程發(fā)送數(shù)據(jù)請求,主線程收到 一直以來都知道JavaScript是一門單線程語言,在筆試過程中不斷的遇到一些輸出結(jié)果的問題,考量的是對異步編程掌握情況。一般被問到異步的時候腦子里第一反應(yīng)就是Ajax,setTimse...
摘要:函數(shù)會在之后的某個時刻觸發(fā)事件定時器。事件循環(huán)中的這樣一次遍歷被稱為一個。執(zhí)行完畢并出棧。當(dāng)定時器過期,宿主環(huán)境會把回調(diào)函數(shù)添加至事件循環(huán)隊列中,然后,在未來的某個取出并執(zhí)行該事件。 原文請查閱這里,略有改動。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現(xiàn)在,我們將會通過回顧單線程環(huán)境下編程的弊端及如何克服這些困難以創(chuàng)建令人驚嘆...
摘要:構(gòu)造函數(shù)的實現(xiàn)我們在使用的時候其實是使用關(guān)鍵字創(chuàng)建了一個的實例,其實是一個類,即構(gòu)造函數(shù),下面來實現(xiàn)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018998456); 閱讀原文 概述 Promise 是 js 異步編程的一種解決方案,避免了 回調(diào)地獄 給編程帶來的麻煩,在 ES6 中成為了標(biāo)準(zhǔn),這篇文章重點不是敘...
摘要:引擎線程也稱為內(nèi)核,負(fù)責(zé)處理腳本程序例如引擎引擎線程負(fù)責(zé)解析腳本,運行代碼。對象代表一個未完成但預(yù)計將來會完成的操作。注意一旦新建就會立即執(zhí)行它屬于,無法取消。 寫在前面: 第一遍學(xué)Promise時, 只是大概過了一遍, 感覺學(xué)的不夠深入, 這一篇算是對之前的一個總結(jié)吧. Promise在ES6中也屬于一個較難理解的一部分; 所以在學(xué)習(xí)一個比較難理解的知識點時, 我們可以圍繞這個知識點...
閱讀 3202·2023-04-25 14:15
閱讀 2883·2021-11-04 16:11
閱讀 3443·2021-10-14 09:42
閱讀 509·2019-08-30 15:52
閱讀 2883·2019-08-30 14:03
閱讀 3623·2019-08-30 13:00
閱讀 2167·2019-08-26 11:40
閱讀 3381·2019-08-26 10:25