亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

js異同步

leanxi / 2877人閱讀

摘要:完成請(qǐng)問(wèn)應(yīng)該如何安排操作流程上面代碼采用個(gè)回調(diào)函數(shù)的嵌套,不僅寫起來(lái)麻煩,容易出錯(cuò),而且難以維護(hù)串行執(zhí)行我們可以編寫一個(gè)流程控制函數(shù),讓它來(lái)控制異步任務(wù),一個(gè)任務(wù)完成以后,再執(zhí)行另一個(gè)。

前言

回調(diào)地獄

js異步

Javascript 語(yǔ)言的執(zhí)行環(huán)境是“單線程”(single thread)。所謂“單線程”,就是指一次只能完成一件任務(wù)。如果有多個(gè)任務(wù),就必須排隊(duì),前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù)。

這種模式的好處是實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,執(zhí)行環(huán)境相對(duì)單純;壞處是只要有一個(gè)任務(wù)耗時(shí)很長(zhǎng),后面的任務(wù)都必須排隊(duì)等著,會(huì)拖延整個(gè)程序的執(zhí)行。常見(jiàn)的瀏覽器無(wú)響應(yīng)(假死),往往就是因?yàn)槟骋欢?JavaScript 代碼長(zhǎng)時(shí)間運(yùn)行(比如死循環(huán)),導(dǎo)致整個(gè)頁(yè)面卡在這個(gè)地方,其他任務(wù)無(wú)法執(zhí)行。

為了解決這個(gè)問(wèn)題,Javascript 語(yǔ)言將任務(wù)的執(zhí)行模式分成兩種:同步(Synchronous)和異步(Asynchronous)。

回調(diào)函數(shù)

假定有兩個(gè)函數(shù)f1和f2,后者必須等到前者執(zhí)行完成,才能執(zhí)行。這時(shí),可以考慮改寫f1,把f2寫成f1的回調(diào)函數(shù)。

  function f1(callback) {
      callback();
  }
事件監(jiān)聽(tīng)
f1.on("done", f2);

function f1(){
  setTimeout(function () {
    // f1的任務(wù)代碼
    f1.trigger("done");
  }, 1000);
}
發(fā)布訂閱
jQuery.subscribe("done", f2);

function f1(){
    setTimeout(function () {
        // f1的任務(wù)代碼
        jQuery.publish("done");
    }, 1000);
}

jQuery.unsubscribe("done", f2);

這種方法的性質(zhì)與”事件監(jiān)聽(tīng)”類似,但是明顯優(yōu)于后者。因?yàn)槲覀兛梢酝ㄟ^(guò)查看”消息中心”,了解存在多少信號(hào)、每個(gè)信號(hào)有多少訂閱者,從而監(jiān)控程序的運(yùn)行。

js異步操作流程控制

如果有多個(gè)異步操作,就存在一個(gè)流程控制的問(wèn)題:確定操作執(zhí)行的順序,以后如何保證遵守這種順序

function async(arg, callback) {
  console.log("參數(shù)為 " + arg +" , 1秒后返回結(jié)果");
  setTimeout(function() { callback(arg * 2); }, 1000);
}

上面代碼的async函數(shù)是一個(gè)異步任務(wù),非常耗時(shí),每次執(zhí)行需要1秒才能完成,然后再調(diào)用回調(diào)函數(shù)。

如果有6個(gè)這樣的異步任務(wù),需要全部完成后,才能執(zhí)行下一步的final函數(shù)。

function final(value) {
  console.log("完成: ", value);
}

請(qǐng)問(wèn)應(yīng)該如何安排操作流程?

async(1, function(value){
  async(value, function(value){
    async(value, function(value){
      async(value, function(value){
        async(value, function(value){
          async(value, final);
        });
      });
    });
  });
});

上面代碼采用6個(gè)回調(diào)函數(shù)的嵌套,不僅寫起來(lái)麻煩,容易出錯(cuò),而且難以維護(hù)

串行執(zhí)行

我們可以編寫一個(gè)流程控制函數(shù),讓它來(lái)控制異步任務(wù),一個(gè)任務(wù)完成以后,再執(zhí)行另一個(gè)。這就叫串行執(zhí)行。(任務(wù)隊(duì)列)

 let taskQueen = [1, 2, 3, 4, 5, 6];
 let result = [];
 function invoke(curTask) {
    if (curTask) {
      console.log("當(dāng)前正在執(zhí)行任務(wù)", curTask);
      result.push(curTask + "完成");
    } else {
      console.log("當(dāng)前任務(wù)全部完成");
    }
 }
 invoke(taskQueen.shift());
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];
function series(item) {
  if(item) {
    async( item, function(result) {
      results.push(result);
      return series(items.shift());
    });
  } else {
    return final(results);
  }
}
series(items.shift());
并行
    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    items.forEach(function(item) {
      async(item, function(result){
        results.push(result);
        if(results.length == items.length) {
          final(results);
        }
      })
    });

上面代碼中,forEach方法會(huì)同時(shí)發(fā)起6個(gè)異步任務(wù),等到它們?nèi)客瓿梢院螅艜?huì)執(zhí)行final函數(shù)。

并行執(zhí)行的好處是效率較高,比起串行執(zhí)行一次只能執(zhí)行一個(gè)任務(wù),較為節(jié)約時(shí)間。但是問(wèn)題在于如果并行的任務(wù)較多,很容易耗盡系統(tǒng)資源,拖慢運(yùn)行速度。因此有了第三種流程控制方式

function launcher() {
  while(running < limit && items.length > 0) {
    var item = items.shift();
    async(item, function(result) {
      results.push(result);
      running--;
      if(items.length > 0) {
        launcher();
      } else if(running == 0) {
        final(results);
      }
    });
    running++;
  }
}

launcher();
promise

Promise 對(duì)象用于一個(gè)異步操作的最終完成(或失敗)及其結(jié)果值的表示。(簡(jiǎn)單點(diǎn)說(shuō)就是處理異步請(qǐng)求。我們經(jīng)常會(huì)做些承諾,如果我贏了你就嫁給我,如果輸了我就嫁給你之類的諾言。這就是promise的中文含義:諾言,一個(gè)成功,一個(gè)失敗。) -MDN

new Promise(
    /* executor */
    function(resolve, reject) {...}
);

一個(gè) Promise有以下幾種狀態(tài):

pending: 初始狀態(tài),不是成功或失敗狀態(tài)。

fulfilled: 意味著操作成功完成。

rejected: 意味著操作失敗。

then()
  var promise = new Promise(function(resolve, reject){
      resolve("傳遞給then的值");
  });
  promise.then(function (value) {
      console.log(value);
  }, function (error) {
      console.error(error);
  });
catch()

捕獲promise 運(yùn)行的各種錯(cuò)誤 promise.then(undefined, onRejected)
的語(yǔ)法糖

var promise = new Promise(function(resolve, reject){
    resolve("傳遞給then的值");
});
promise.then(function (value) {
    console.log(value);
}).catch(function (error) {
    console.error(error);
});
Promise.resolve && Promise.reject Promise.all

生成并返回一個(gè)新的promise對(duì)象。

參數(shù)傳遞promise數(shù)組中所有的promise對(duì)象都變?yōu)閞esolve的時(shí)候,該方法才會(huì)返回, 新創(chuàng)建的promise則會(huì)使用這些promise的值。

如果參數(shù)中的任何一個(gè)promise為reject的話,則整個(gè)Promise.all調(diào)用會(huì)立即終止,并返回一個(gè)reject的新的promise對(duì)象。

由于參數(shù)數(shù)組中的每個(gè)元素都是由 Promise.resolve 包裝(wrap)的,所以Paomise.all可以處理不同類型的promose對(duì)象。

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    console.log(results);  // [1, 2, 3]
});
Promise.race
var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.race([p1, p2, p3]).then(function (value) {
    console.log(value);  // 1
});

生成并返回一個(gè)新的promise對(duì)象。

參數(shù) promise 數(shù)組中的任何一個(gè)promise對(duì)象如果變?yōu)閞esolve或者reject的話, 該函數(shù)就會(huì)返回,并使用這個(gè)promise對(duì)象的值進(jìn)行resolve或者reject。

參考

JavaScript Promise迷你書(中文版)

promise阮一峰(http://javascript.ruanyifeng....

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/89043.html

相關(guān)文章

  • 數(shù)據(jù)脫敏大數(shù)據(jù)架構(gòu)設(shè)計(jì)

    摘要:需求背景系統(tǒng)有數(shù)據(jù)識(shí)別數(shù)據(jù)脫敏邏輯,支持可配置規(guī)則,自定義等,需要進(jìn)行異構(gòu)數(shù)據(jù)同步,大數(shù)據(jù)量??捎眯苑治隹捎眯员砀穹治鰣?chǎng)景影響降級(jí)原因某臺(tái)數(shù)據(jù)同步下線無(wú)影響數(shù)據(jù)同步無(wú)狀態(tài),調(diào)度平臺(tái)重連其他的數(shù)據(jù)同步服務(wù)。 需求背景 系統(tǒng)有數(shù)據(jù)識(shí)別、數(shù)據(jù)脫敏邏輯,支持可配置規(guī)則,自定義等,需要進(jìn)行異構(gòu)數(shù)據(jù)同步,大數(shù)據(jù)量?,F(xiàn)在針對(duì)以下幾個(gè)需求進(jìn)行講解 1、支持冗余設(shè)計(jì)2、支持任務(wù)自動(dòng)分發(fā),支持自動(dòng)負(fù)載均衡...

    lavor 評(píng)論0 收藏0
  • SpringCloud(第 026 篇)簡(jiǎn)單構(gòu)系統(tǒng)之 nodejs 微服務(wù)

    摘要:第篇簡(jiǎn)單異構(gòu)系統(tǒng)之微服務(wù)一大致介紹因?yàn)樵诤竺嬉眉僧悩?gòu)系統(tǒng),所以才有了本章節(jié)的微服務(wù)本章節(jié)使用了最簡(jiǎn)單的請(qǐng)求截取的方式,截取不同的后綴做不同的響應(yīng)處理,簡(jiǎn)直二實(shí)現(xiàn)步驟添加服務(wù)端文件引入模塊創(chuàng)建獲得請(qǐng)求的路徑訪問(wèn),將會(huì)返回歡迎 SpringCloud(第 026 篇)簡(jiǎn)單異構(gòu)系統(tǒng)之 nodejs 微服務(wù) - 一、大致介紹 1、因?yàn)樵诤竺嬉?SpringCloud 集成異構(gòu)系統(tǒng),所...

    raledong 評(píng)論0 收藏0
  • JS基礎(chǔ)——同步步的區(qū)別

    摘要:只要指定過(guò)這些事件的回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入任務(wù)隊(duì)列,等待主線程讀取。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開(kāi)始執(zhí)行異步任務(wù),就是執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。 javascript語(yǔ)言是一門單線程的語(yǔ)言,不像java語(yǔ)言,類繼承Thread再來(lái)個(gè)thread.start就可以開(kāi)辟一個(gè)線程。所以,javascript就像一條流水線,僅僅是一條流水線而已,要么加工,要么包裝,不能同時(shí)進(jìn)行多個(gè)任...

    ztyzz 評(píng)論0 收藏0
  • Java String類筆記

    摘要:這兩個(gè)操作符都是編譯器默認(rèn)引入了類,最后都調(diào)用方法返回對(duì)象,臨時(shí)對(duì)象被回收,因此效率極為低下 Java String類筆記 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處https://segmentfault.com/u/yzwall String的不可變性 String的不可變性 // String declaration public final class String ...

    Vicky 評(píng)論0 收藏0
  • 阻塞,非阻塞,步,同步

    摘要:出場(chǎng)人物老張,水壺兩把普通水壺,簡(jiǎn)稱水壺會(huì)響的水壺,簡(jiǎn)稱響水壺。同步非阻塞老張還是覺(jué)得自己有點(diǎn)傻,于是變高端了,買了把會(huì)響笛的那種水壺。所謂阻塞非阻塞,僅僅對(duì)于老張而言。 1、例子 老張愛(ài)喝茶,廢話不說(shuō),煮開(kāi)水。出場(chǎng)人物:老張,水壺兩把(普通 水壺,簡(jiǎn)稱水壺;會(huì)響的水壺,簡(jiǎn)稱響水壺)。 1 老張把水壺放到火上,立等水開(kāi)。(同步阻塞) 老張覺(jué)得自己有點(diǎn)傻 2 老張把...

    AZmake 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<