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

資訊專欄INFORMATION COLUMN

JavaScript 并行和串行任務/流程控制 的實現

bladefury / 535人閱讀

摘要:并行和串行任務在里面異步是一個很重要的知識點的異步跟其他語言不一樣他是根據執(zhí)行回調的方式來實現的。在之前,執(zhí)行任務想要實現這個流程控制只能通過依賴來實現或者通過而在之后官方自己實現了和來實現。

JavaScript 并行和串行任務

在 JavaScript 里面 異步 是一個很重要的知識點,JS 的異步跟其他語言不一樣, 他是根據執(zhí)行回調的方式來 實現的。由于我們不知道異步什么時候會執(zhí)行完,讓一組異步任務順序執(zhí)行就顯得很重要了,這個時候我們就需要 流程控制 ,這種流程控制有兩種 串行(series)并行(parallel)

實際開發(fā)中也許你在 JS 中很少接觸到這個 并行串行 ,但是如果你接觸過 gulp 我相信你應該對這個概念并不陌生.因為在 gulp 里面編寫 task 到處充斥著這種異步執(zhí)行。在 gulp(4.0)之前,執(zhí)行任務想要實現這個流程控制只能通過 依賴 來實現或者通過 run-sequence,而在 gulp(4.0)之后官方自己實現了 gulp.seriesgulp.parallel 來實現。如果之前沒有接觸過 gulp 有興趣的可以了解下(雖然現在是 Webpack 的世界~~~)

而如果對于 串行并行 有所接觸的話,一般都會使用一個叫 nimble,但是我個人對于這個庫里面實現 并行 功能是有疑問的.疑問點在于他不是按照我想象的工作方式工作

串行的簡單實現

串行的實現有點像 Koa 里面對于中間件的實現。通過一個 next 函數來觸發(fā)下一個函數的執(zhí)行。

// 或者使用reduce
let series = function(arr) {
  let index = 0;
  let next = function() {
    if (index >= arr.length) {
      return;
    }
    arr[index](next);
    index++;
  };
  next();
};

這是一個基本的實現邏輯,實現的方式有點粗糙,其實我們每次取出的函數的方式可以進行一個優(yōu)化,不需要中間變量 index 來記錄當前的執(zhí)行函數,而是通過 Array.prototype.shift 去取數組里面的函數用來執(zhí)行

let series = function(arr) {
  let next = function(data) {
    let fn = arr.shift();
    if (!fn) {
      return;
    }
    fn(next,data);
  };
  next();
};

// 使用方法
let str = "";
series([
  function(next) {
    setTimeout(function() {
      str = "Hello"
      next(str);
    }, 100);
  },
  function(next,data) {
    setTimeout(function() {
      str += "World"
      console.log(str)
      console.log(data);
      next();
    });
  }
]);
并行的簡單實現

剛剛在上面提到過,我對于 nimble 中 并行的實現是有疑問的,他并沒有按照我上面的 圖片執(zhí)行,少了我覺得很重要的一步 并行應該又一個最終的函數,這個函數要等其他函數執(zhí)行完畢才會執(zhí)行

假設我有三個需要并行執(zhí)行的函數 fn1,fn2,fn3。 當這三個函數執(zhí)行之后應該需要在時間最晚的函數內執(zhí)行一個最終的函數,來 處理一些依賴邏輯。下面是我個人的 簡單實現代碼

let parallel = function(arr, finnaly) {
  let fn,
    index = 0;
  let statusArr = Array(arr.length)
    .fill()
    .map(() => ({
      isActive: false,
      data: null
    }));
  let isFinished = function() {
    return statusArr.every(item => {
      return item.isActive === true;
    });
  };
  let resolve = function(index) {
    return function(data) {
      statusArr[index].data = data;
      statusArr[index].isActive = true;
      let isFinish = isFinished();
      if (isFinish) {
        let datas = statusArr.map(item => {
          return item.data;
        });
        finnaly(datas);
      }
    };
  };
  while ((fn = arr.shift())) {
    // 給resolve函數追加參數,可以使用bind函數實現,這里使用了柯里化
    fn(resolve(index));
    index++;
  }
};

// 使用方法
let str = "";
parallel(
  [
    function(resolve) {
      setTimeout(function() {
        str = "Hello";
        resolve("Hello");
      }, 1000);
    },
    function(resolve) {
      setTimeout(function() {
        str += "World";
        resolve("World");
      }, 20);
    }
  ],
  function(datas) {
    console.log("finily", datas);
  }
);
關于其他

以上就是簡單的 串行并行 實現的基本方案, 有一些地方用到了 ES6,希望讀者不要介意。其實如果你是 面向ES6開發(fā) 的話。更簡單的方式是用 Promise 的方案,甚至可以使用 async/awaitgenerator 這些高級方法,來使 異步 代碼跟同步一樣使用,使代碼的可讀性更高

// 并行
let datas = await Promise.all([
  new Promise(resolve => {
    setTimeout(resolve.bind(this,10), 1000);
  }),
  new Promise(resolve => {
    setTimeout(resolve.bind(this,12), 2000);
  })
])

// 串行
let data1 = await new Promise(resolve => {
  setTimeout(resolve.bind(this, 10), 1000);
})
let data2 = await new Promise(resolve => {
  setTimeout(resolve.bind(this, 12), 1000);
});

這樣看起來是不是很簡潔

ES6 大法好?。。?/b> ES6 大法好?。。?/b> ES6 大法好?。?!

重要事情說三遍
相信你看出來了吧,這篇文章其實是來宣傳ES6的,不過還是希望大家能了解一下底層的實現。另外有一篇 Promise的實現。寫的相當好,極力推薦閱讀一下

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

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/107422.html

相關文章

  • 異步操作(一)概述

    摘要:回調函數指定了下一步操作。異步操作的流程控制參數為秒后返回結果上面代碼的函數是一個異步任務,非常耗時,每次執(zhí)行需要秒才能完成,然后再調用回調函數。 單線程模型同步任務和異步任務任務隊列和事件循環(huán)異步操作的模式回調函數事件監(jiān)聽發(fā)布/訂閱異步操作的流程控制串行執(zhí)行并行執(zhí)行并行與串行的結合 1.單線程模型指的是js只在線程運行,一個時間執(zhí)行一個任務,其他任務排隊。事實上是一個運行腳本的主線程...

    wemall 評論0 收藏0
  • js異同步

    摘要:完成請問應該如何安排操作流程上面代碼采用個回調函數的嵌套,不僅寫起來麻煩,容易出錯,而且難以維護串行執(zhí)行我們可以編寫一個流程控制函數,讓它來控制異步任務,一個任務完成以后,再執(zhí)行另一個。 前言 回調地獄showImg(https://segmentfault.com/img/remote/1460000011554165?w=1000&h=710); js異步 Javascript 語...

    leanxi 評論0 收藏0
  • Nodejs異步流程框架async

    摘要:如果任何函數發(fā)生錯誤,會立刻執(zhí)行回調函數,并返回錯誤信息若沒有發(fā)生錯誤,則會再所有函數執(zhí)行完畢之后用回掉函數將結果返回。 Async的簡單介紹: Async是一個流程控制工具包,提供了直接而強大的異步功能?;贘avascript為Node.js設計,同時也可以直接在瀏覽器中使用。Async提供了大約20個函數,包括常用的map, reduce, filter, forEach等,異步...

    miya 評論0 收藏0
  • java高并發(fā)系列 - 第3天:有關并行兩個重要定律

    摘要:阿姆達爾定律定律是計算機科學中非常重要的定律。它定義了串行系統(tǒng)并行化后的加速比的計算公式和理論上線。需要從根本上修改程序的串行行為,提高系統(tǒng)內可并行化的模塊比重,在此基礎上,合理增加并行處理器數量,才能以最小的投入,得到最大的加速比。 有關為什么要使用并行程序的問題前面已經進行了簡單的探討。總的來說,最重要的應該是處于兩個目的。 第一,為了獲得更好的性能; 第二,由于業(yè)務模型的需要,確...

    liaoyg8023 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<