91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript之生成器_動力節點Java學院整理

發布時間:2020-10-14 23:37:28 來源:腳本之家 閱讀:125 作者:liaoxuefeng 欄目:web開發

generator(生成器)是ES6標準引入的新的數據類型。一個generator看上去像一個函數,但可以返回多次。

我們先復習函數的概念。一個函數是一段完整的代碼,調用一個函數就是傳入參數,然后返回結果:

function foo(x) {
 return x + x;
}
var r = foo(1); // 調用foo函數

函數在執行過程中,如果沒有遇到return語句(函數末尾如果沒有return,就是隱含的return undefined;),控制權無法交回被調用的代碼。

generator跟函數很像,定義如下:

function* foo(x) {
 yield x + 1;
 yield x + 2;
 return x + 3;
}

generator和函數不同的是,generator由function*定義(注意多出的*號),并且,除了return語句,還可以用yield返回多次。

大多數同學立刻就暈了,generator就是能夠返回多次的“函數”?返回多次有啥用?

還是舉個栗子吧。

我們以一個著名的斐波那契數列為例,它由0,1開頭:

0 1 1 2 3 5 8 13 21 34 ...

要編寫一個產生斐波那契數列的函數,可以這么寫:

function fib(max) {
 var
  t,
  a = 0,
  b = 1,
  arr = [0, 1];
 while (arr.length < max) {
  t = a + b;
  a = b;
  b = t;
  arr.push(t);
 }
 return arr;
}

// 測試:
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

函數只能返回一次,所以必須返回一個Array。但是,如果換成generator,就可以一次返回一個數,不斷返回多次。用generator改寫如下:

function* fib(max) {
 var
  t,
  a = 0,
  b = 1,
  n = 1;
 while (n < max) {
  yield a;
  t = a + b;
  a = b;
  b = t;
  n ++;
 }
 return a;
}

直接調用試試:

復制代碼 代碼如下:

fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}

直接調用一個generator和調用函數不一樣,fib(5)僅僅是創建了一個generator對象,還沒有去執行它。

調用generator對象有兩個方法,一是不斷地調用generator對象的next()方法:

var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: true}

next()方法會執行generator的代碼,然后,每次遇到yield x;就返回一個對象{value: x, done: true/false},然后“暫停”。返回的value就是yield的返回值,done表示這個generator是否已經執行結束了。如果donetrue,則value就是return的返回值。

當執行到donetrue時,這個generator對象就已經全部執行完畢,不要再繼續調用next()了。

第二個方法是直接用for ... of循環迭代generator對象,這種方式不需要我們自己判斷done

for (var x of fib(5)) {
 console.log(x); // 依次輸出0, 1, 1, 2, 3
}

generator和普通函數相比,有什么用?

因為generator可以在執行過程中多次返回,所以它看上去就像一個可以記住執行狀態的函數,利用這一點,寫一個generator就可以實現需要用面向對象才能實現的功能。例如,用一個對象來保存狀態,得這么寫:

var fib = {
 a: 0,
 b: 1,
 n: 0,
 max: 5,
 next: function () {
  var
   r = this.a,
   t = this.a + this.b;
  this.a = this.b;
  this.b = t;
  if (this.n < this.max) {
   this.n ++;
   return r;
  } else {
   return undefined;
  }
 }
};

用對象的屬性來保存狀態,相當繁瑣。

generator還有另一個巨大的好處,就是把異步回調代碼變成“同步”代碼。這個好處要等到后面學了AJAX以后才能體會到。

沒有generator之前的黑暗時代,用AJAX時需要這么寫代碼:

ajax('http://url-1', data1, function (err, result) {
 if (err) {
  return handle(err);
 }
 ajax('http://url-2', data2, function (err, result) {
  if (err) {
   return handle(err);
  }
  ajax('http://url-3', data3, function (err, result) {
   if (err) {
    return handle(err);
   }
   return success(result);
  });
 });
});

回調越多,代碼越難看。

有了generator的美好時代,用AJAX時可以這么寫:

try {
 r1 = yield ajax('http://url-1', data1);
 r2 = yield ajax('http://url-2', data2);
 r3 = yield ajax('http://url-3', data3);
 success(r3);
}
catch (err) {
 handle(err);
}

看上去是同步的代碼,實際執行是異步的。

練習

要生成一個自增的ID,可以編寫一個next_id()函數

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

禄丰县| 东乡族自治县| 巴青县| 哈密市| 如皋市| 买车| 泾川县| 博湖县| 砀山县| 华宁县| 清涧县| 拉萨市| 汶川县| 改则县| 江川县| 光山县| 石台县| 阿拉善左旗| 铅山县| 南漳县| 朝阳县| 陇西县| 青阳县| 子长县| 普宁市| 万荣县| 蕲春县| 建平县| 永平县| 岳普湖县| 陈巴尔虎旗| 西青区| 旺苍县| 五华县| 晋城| 枞阳县| 仲巴县| 丹棱县| 剑阁县| 龙南县| 湘潭市|