国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Promise-resolve流程源碼剖析

Amos / 1817人閱讀

原文鏈接:鏈接

1 最簡(jiǎn)單一個(gè)案例
function runAsync(){
  let p = new Promise(function(resolve,reject){
    console.log("exec");
    setTimeout(function(){
      resolve("someData");
    },2000);
  });
  return  p;
}
var promise = runAsync();
promise.then(function(data){
  console.log(data);
});
console.log("同步執(zhí)行");
console.log(promise);

控制臺(tái)輸出

exec
同步執(zhí)行
Promise
//兩秒后
someData
2 Promise內(nèi)部是如何運(yùn)行的? 2.1 執(zhí)行這行代碼的時(shí)候:let p = new Promise(f);
function noop() {}
function Promise(fn) {
  if (typeof this !== "object") {
    throw new TypeError("Promises must be constructed via new");
  }
  if (typeof fn !== "function") {
    throw new TypeError("Promise constructor"s argument is not a function");
  }
  this._deferredState = 0;
  this._state = 0;
  this._value = null;
  this._deferreds = null;
  //注意這里,如果fn傳入的是noop這個(gè)函數(shù),那么不會(huì)執(zhí)行doResolve
  if (fn === noop) return;
  doResolve(fn, this);
}
Promise._onHandle = null;
Promise._onReject = null;
Promise._noop = noop;
function doResolve(fn, promise) {
  var done = false;
  var res = tryCallTwo(fn, function (value) {
    if (done) return;
    done = true;
    resolve(promise, value);
  }, function (reason) {
    if (done) return;
    done = true;
    reject(promise, reason);
  });
  if (!done && res === IS_ERROR) {
    done = true;
    reject(promise, LAST_ERROR);
  }
}
function tryCallTwo(fn, a, b) {
  try {
    fn(a, b);
  } catch (ex) {
    LAST_ERROR = ex;
    return IS_ERROR;
  }
}

可以看到 let p = new Promise( f );在 傳入的 f. 函數(shù)不是noop的時(shí)候,

第一會(huì)先執(zhí)行 f 函數(shù)

第二生成一個(gè)Promise對(duì)象

p =>{
  _deferredState:0,//deffer的狀態(tài),代表的應(yīng)該是 _deferreds 的類型,1 是 single,2 是 Array
  _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds:null  
}
2.2執(zhí)行這行代碼的時(shí)候: promise.then(function(data){ console.log(data);});
Promise.prototype.then = function(onFulfilled, onRejected) {
  if (this.constructor !== Promise) {//這些比較的都是引用地址;
    return safeThen(this, onFulfilled, onRejected);
  }
  var res = new Promise(noop);
  handle(this, new Handler(onFulfilled, onRejected, res));
  //注意這里 then的鏈?zhǔn)秸{(diào)用,每次then函數(shù)執(zhí)行完畢之后,返回值都是一個(gè)新的Promise實(shí)例對(duì)象,
  return res;
};
//這里生成一個(gè)deffer對(duì)象,保存then函數(shù)中注冊(cè)的onFulfilled和onRejected回調(diào),以及要返回的新的promise實(shí)例對(duì)象
function Handler(onFulfilled, onRejected, promise){
  this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null;
  this.onRejected = typeof onRejected === "function" ? onRejected : null;
  this.promise = promise;
}
function handle(self, deferred) {
  //不會(huì)進(jìn)入這里
  while (self._state === 3) {
    self = self._value;
  }
  //也不會(huì)進(jìn)入這里
  if (Promise._onHandle) {
    Promise._onHandle(self);
  }
  //進(jìn)入這里,注意這里,如果通過then的鏈?zhǔn)秸{(diào)用,那么每次then返回的對(duì)象都是一個(gè)新的類似于下面 p 實(shí)例對(duì)象;
  if (self._state === 0) {
    if (self._deferredState === 0) {
      self._deferredState = 1;
      self._deferreds = deferred;
      return;
      //第一次執(zhí)行到這里即結(jié)束;
    }
    if (self._deferredState === 1) {
      self._deferredState = 2;
      self._deferreds = [self._deferreds, deferred];
      return;
    }
    self._deferreds.push(deferred);
    return;
  }
  //這個(gè)函數(shù)只有當(dāng) _state的值為 1 2的時(shí)候才會(huì)執(zhí)行
  handleResolved(self, deferred);
}

此時(shí)再來看下p這個(gè)promise實(shí)例的屬性值

p =>{
  _deferredState:1,//deffer的狀態(tài)
  _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds: new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象;
}
res:{
  _deferredState:0,//deffereds的狀態(tài),
  _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds:null  
}

如果返回的res在執(zhí)行then方法,那么

p =>{
  _deferredState:1,//deffer的狀態(tài)
  _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds: new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象;
}
res:{
  _deferredState:1,//deffereds的狀態(tài),
  _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds:new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象; 
}
2.3 異步操作完成以后:resolve("someData");
//真正調(diào)用這個(gè)函數(shù)的是tryCallTwo中的第二個(gè)函數(shù)入?yún)ⅲ籹elf就是p這個(gè)promise實(shí)例對(duì)象;
function resolve(self, newValue) {
  // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
  //對(duì)于此時(shí)的案例,不會(huì)進(jìn)入這里
  if (newValue === self) {
    return reject(
      self,
      new TypeError("A promise cannot be resolved with itself.")
    );
  }
  //也不會(huì)進(jìn)入這里
  if (
    //比如resolve(p1)   p1是一個(gè)新的promise對(duì)象;
    newValue &&
    (typeof newValue === "object" || typeof newValue === "function")
  ) {
    var then = getThen(newValue);
    if (then === IS_ERROR) {
      return reject(self, LAST_ERROR);
    }
    if (
      then === self.then &&
      newValue instanceof Promise
    ) {
      self._state = 3;
      self._value = newValue;
      finale(self);
      return;
    } else if (typeof then === "function") {
      doResolve(then.bind(newValue), self);
      return;
    }
  }
  //對(duì)于簡(jiǎn)單的返回值,比如后臺(tái)返回的JSON字符串等,這里就直接進(jìn)行處理;
  self._state = 1;//fulfilled
  self._value = newValue;//給這個(gè)promise對(duì)象添加屬性值 _value,用來保存異步操作的結(jié)果;
  finale(self);//最后處理這個(gè)promise對(duì)象
}

此時(shí)的promise實(shí)例對(duì)象,關(guān)注對(duì)比p這個(gè)實(shí)例對(duì)象的變化,可以看到resolve之后,相當(dāng)于將異步的結(jié)果給到了p這個(gè)Promise實(shí)例對(duì)象的_value屬性值,同時(shí)改變這個(gè)p的狀態(tài)_state為1 ==> fulfilled

p =>{
  _deferredState:1,//deffer的狀態(tài)
  _state:1,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
  _value:"someData",//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
  _deferreds: new Handler(onFulfilled, onRejected, res)
}
2.4 finale(self);//最后處理這個(gè)promise對(duì)象
function finale(self) {
  //進(jìn)入這個(gè)if語(yǔ)句
  if (self._deferredState === 1) {
    handle(self, self._deferreds);
    self._deferreds = null;
  }
  if (self._deferredState === 2) {
    for (var i = 0; i < self._deferreds.length; i++) {
      handle(self, self._deferreds[i]);
    }
    self._deferreds = null;
  }
}
function handle(self, deferred) {
  while (self._state === 3) {
    self = self._value;
  }
  if (Promise._onHandle) {
    Promise._onHandle(self);
  }
  //此時(shí)不會(huì)進(jìn)入這里因?yàn)?_state的值為 1 
  if (self._state === 0) {
    if (self._deferredState === 0) {
      self._deferredState = 1;
      self._deferreds = deferred;
      return;
    }
    if (self._deferredState === 1) {
      self._deferredState = 2;
      self._deferreds = [self._deferreds, deferred];
      return;
    }
    self._deferreds.push(deferred);
    return;
  }
    //這個(gè)函數(shù)只有當(dāng) _state的值為 1 fulfilled. 2  rejected 的時(shí)候才會(huì)執(zhí)行
  handleResolved(self, deferred);
}
function handleResolved(self, deferred) {
  asap(function() {
    //得到promise.then(function(data){ console.log(data);});注冊(cè)的函數(shù)
    var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
    if (cb === null) {
      if (self._state === 1) {
        resolve(deferred.promise, self._value);
      } else {
        reject(deferred.promise, self._value);
      }
      return;
    }
    //執(zhí)行then中注冊(cè)回調(diào)函數(shù)
    var ret = tryCallOne(cb, self._value);
    if (ret === IS_ERROR) {
      reject(deferred.promise, LAST_ERROR);
    } else {
      resolve(deferred.promise, ret);
    }
  });
};
function tryCallOne(fn, a) {
  try {
    return fn(a);
  } catch (ex) {
    LAST_ERROR = ex;
    return IS_ERROR;
  }
}

至此一個(gè)簡(jiǎn)單的promsie的實(shí)現(xiàn)流程完畢;

下面用實(shí)際的例子來看下:

3 對(duì)于then的鏈?zhǔn)秸{(diào)用,Promise內(nèi)部又是如何運(yùn)行的呢? 下一個(gè)then中注冊(cè)的函數(shù)會(huì)接收到上一個(gè)then的返回值作為該then中注冊(cè)的函數(shù)的參數(shù); 3.1 then注冊(cè)的函數(shù)返回基本數(shù)據(jù)類型
function runAsync(){
  let p = new Promise(function(resolve,reject){
    console.log("exec");
    setTimeout(function(){
      resolve("someData");
    },2000);
  });
  return  p;
}
var promise = runAsync();
promise.then(function(data){
  console.log(data);
  return "someData1"
}).then(function(data){
  console.log(data);
  return "someData2"
}).then(function(data){
  console.log(data)
})
console.log("同步執(zhí)行");
console.log(promise);

控制臺(tái)輸出

exec
同步執(zhí)行
Promise
//兩秒后
someData
someData1
someData2

resolve(deferred.promise, ret);中的ret值就是then中注冊(cè)函數(shù)的返回值,這里就是一些簡(jiǎn)單的字符串"someData1" "someData2"

promise實(shí)例對(duì)象==> 異步成功 ==> 該實(shí)例對(duì)象的resolve(data) ==> 
//newValue為異步得到的數(shù)據(jù),第一次是"someData"這個(gè)字符串,下一次就是then中注冊(cè)函數(shù)的返回值ret,還是字符串"someData1" "someData2" 
resolve(self,newValue)     ==>            <== == == == ==  == ==  ||
                                                                ^
==>handle(self,deffer)                                             ||
                                                                ^    
==>handleResolved處理then中注冊(cè)的函數(shù);                              ||
                                                                ^
==>接著處理下一個(gè)promis==>resolve(deferred.promise, ret);    ===> ||
 var p = {
        _deferredState:1,//deffer的狀態(tài)
        _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
        _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
        _deferreds:{ 
            onFulfilled:onFulfilled,
            onRejected:onRejected,
            promise:{//這里是  new Promise(noop)
                _deferredState:1,
                _state:0,
                _value:null,
                _deferreds:{//通過then注冊(cè)的執(zhí)行對(duì)象
                    onFulfilled:onFulfilled,
                    onRejected:onRejected,
                    promise:{//這里是  new Promise(noop)
                        _deferredState:1,
                        _state:0,
                        _value:null,
                        _deferreds:{//通過then注冊(cè)的執(zhí)行對(duì)象
                            onFulfilled:onFulfilled,
                            onRejected:onRejected,
                            promise:{//這里是  new Promise(noop)
                                _deferredState:1
                                _state:0,
                                _value:null,
                                _deferreds:null
                            },
                        }
                    }
                }
            }
        }
    };
3.2 then注冊(cè)的函數(shù)返回一個(gè)新的promise
function runAsync(){
  let p = new Promise(function(resolve,reject){
    console.log("exec");
    setTimeout(function(){
      resolve("someData");
    },2000);
  });
  return  p;
};
function runAsync1(){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      resolve("someData1");
    },2000);
  })
};
function runAsync2(){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      resolve("someData2");
    },2000);
  })
};
//以下的異步操作會(huì)按照順序進(jìn)行執(zhí)行;
var promise = runAsync();
promise.then(function(data){
  console.log(data);
  return runAsync1()
}).then(function(data){
  console.log(data);
  return runAsync2()
}).then(function(data){
  console.log(data);
  // return "someData3"
})
console.log("同步執(zhí)行");
console.log(promise);

控制臺(tái)輸出

exec
同步執(zhí)行
Promise
//兩秒后
someData
//兩秒后
someData1
//兩秒后
someData2
promise實(shí)例對(duì)象 ==> 異步成功 ==> 該實(shí)例對(duì)象的resolve(data) ==> 
//newValue為異步得到的數(shù)據(jù),這里第一次是 "someData"這個(gè)字符串,下一次就是then中注冊(cè)函數(shù)的返回值,這里就是runAsync返回的promise對(duì)象
resolve(self,newValue)    ==>            <== == == == ==  == ==  ||
                                                                ^
==>handle(self,deffer)                                             ||
                                                                ^
==>handleResolved處理then中注冊(cè)的函數(shù);                              ||
                                                                ^
==>接著處理下一個(gè)promise==>resolve(deferred.promise, ret);    ===> ||

整個(gè)promise鏈如下

 var p = {
        _deferredState:1,//deffer的狀態(tài)
        _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí)
        _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果
        _deferreds:{ 
            onFulfilled:onFulfilled,
            onRejected:onRejected,
            promise:{ //通過引用的地址改變,這里是runAsync返回的promise
                _deferredState:1,
                _state:0,
                _value:null,
                _deferreds:{//由于runAsync中沒有執(zhí)行then注冊(cè),這里將new Promise(noop) 通過then注冊(cè)的對(duì)象引用拿到;
                    onFulfilled:onFulfilled,
                    onRejected:onRejected,
                    promise:{//通過引用的地址改變,這里是runAsync返回的promise
                        _deferredState:1,
                        _state:0,
                        _value:null,
                        _deferreds:{
                            onFulfilled:onFulfilled,
                            onRejected:onRejected,
                            promise:{//通過引用的地址改變,這里是runAsync返回的promise
                                _deferredState:1,
                                _state:0,
                                _value:null,
                                _deferreds:null
                            },
                        }
                    }
                }
            }
        }
    }
3.3 以上兩者有何差異?

相同點(diǎn):每個(gè)then返回的新的promise對(duì)象是一樣的,都是通過then函數(shù)中的定義的返回值:var res = new Promise(noop);

不同點(diǎn):在handleResolved中,resolve(deferred.promise, ret);中的ret的值不同,ret就是每個(gè)then中注冊(cè)的函數(shù)的返回值,對(duì)比以上兩種情況,一個(gè)返回基本數(shù)據(jù)類型,一個(gè)返回Promise對(duì)象,接下來重點(diǎn)看下then中注冊(cè)的函數(shù)返回promise對(duì)象的情況(注意這個(gè)和then鏈?zhǔn)秸{(diào)用的promise對(duì)象不是一個(gè))

 // resolve(deferred.promise, ret);注意這個(gè)self,傳入的是deferred這個(gè)對(duì)象中promise這個(gè)引用地址;
//真正調(diào)用這個(gè)函數(shù)的是tryCallTwo中的第二個(gè)函數(shù)入?yún)ⅲ籹elf就是p這個(gè)promise實(shí)例對(duì)象;
function resolve(self, newValue) {
  //此時(shí)的newValue是then中注冊(cè)函數(shù)的返回的Promise實(shí)例對(duì)象
  //self是deferred.promise
  // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
  //對(duì)于此時(shí)的案例,不會(huì)進(jìn)入這里
  if (newValue === self) {
    return reject(
      self,
      new TypeError("A promise cannot be resolved with itself.")
    );
  }
  //注意,對(duì)于then中注冊(cè)的函數(shù)返回值是一個(gè)新的promise對(duì)象的時(shí)候,此時(shí)會(huì)進(jìn)入這里
  if (
    //比如resolve(p1)   p1是一個(gè)新的promise對(duì)象;
    newValue &&
    (typeof newValue === "object" || typeof newValue === "function")
  ) {
    var then = getThen(newValue);
    if (then === IS_ERROR) {
      return reject(self, LAST_ERROR);
    }
    if (
      //兩個(gè)Promise對(duì)象原型鏈上都是引用的then這個(gè)函數(shù)地址
      then === self.then &&
      newValue instanceof Promise
    ) {
      self._state = 3;
      self._value = newValue;
      finale(self);
      //執(zhí)行到這里,結(jié)束;
      return;
    } else if (typeof then === "function") {
      doResolve(then.bind(newValue), self);
      return;
    }
  }
//對(duì)于then中注冊(cè)的函數(shù)返回一個(gè)promise對(duì)象的情況,下面就不會(huì)執(zhí)行
  self._state = 1;
  self._value = newValue;
  finale(self);
}

self ==> deferred.promise

function finale(self) {
  if (self._deferredState === 1) {
    handle(self, self._deferreds);
    self._deferreds = null;
  }
  if (self._deferredState === 2) {
    for (var i = 0; i < self._deferreds.length; i++) {
      handle(self, self._deferreds[i]);
    }
    self._deferreds = null;
  }
}

注意在這里通過對(duì)promise鏈進(jìn)行引用的改變,從而使異步的執(zhí)行看起來和同步是一樣的;

handle函數(shù)有兩個(gè)作用,

第一:改變promise鏈的引用,將原本返回的 new Promsie(noop) 改為ret(then中注冊(cè)函數(shù)返回的promise)

第二:將原本new Promsie(noop) 上面通過then注冊(cè)deferred對(duì)象,給到ret響應(yīng)的屬性

function handle(self, deferred) {
  while (self._state === 3) {
    //這里一直循環(huán)直到取到我們返回的promsie對(duì)象,也就是上面的ret,即每個(gè)runAsync函數(shù)的返回值;
    self = self._value;
  }
  if (Promise._onHandle) {
    Promise._onHandle(self);
  }
  //將runAsync的返回的promise對(duì)象中_deferredState設(shè)置為 1;
  if (self._state === 0) {
    if (self._deferredState === 0) {
      self._deferredState = 1;
      self._deferreds = deferred;
      //執(zhí)行到這里結(jié)束
      return;
    }
    if (self._deferredState === 1) {
      self._deferredState = 2;
      self._deferreds = [self._deferreds, deferred];
      return;
    }
    self._deferreds.push(deferred);
    return;
  }
  handleResolved(self, deferred);
}
4 綜合練習(xí)

對(duì)于注釋的代碼可以來回切換,看下結(jié)果。

function runAsync(){
  let p = new Promise(function(resolve,reject){
    console.log("exec");
    setTimeout(function(){
      resolve("someData");
    },2000);
  });
  return  p;
};
function runAsync1(){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      console.log("異步1")
      // resolve("someData1");
      reject("error1")
    },2000);
  })
};
function runAsync2(){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      console.log("異步2")
      // resolve("someData2");
      reject("error2")
    },2000);
  })
}
var promise = runAsync();
promise.then(function(data){
  console.log(data);
  return runAsync1()
}).then(function(data){
  console.log(data);
  return runAsync2()
}).then(function(data){
  console.log(data);
  // return "someData3"
}).catch(function(error){
  console.log(error)
})
console.log("同步執(zhí)行");
console.log(promise);

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92272.html

相關(guān)文章

  • vue.js源碼 - 剖析observer,dep,watch三者關(guān)系 如何具體的實(shí)現(xiàn)數(shù)據(jù)雙向綁定

    摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。 Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于d...

    mo0n1andin 評(píng)論0 收藏0
  • 剖析 React 源碼:render 流程(一)

    摘要:大家可以看到是構(gòu)造函數(shù)構(gòu)造出來的,并且內(nèi)部有一個(gè)對(duì)象,這個(gè)對(duì)象是本文接下來要重點(diǎn)介紹的對(duì)象,接下來我們就來一窺究竟吧。在構(gòu)造函數(shù)內(nèi)部就進(jìn)行了一步操作,那就是創(chuàng)建了一個(gè)對(duì)象,并掛載到了上。下一篇文章還是流程相關(guān)的內(nèi)容。這是我的剖析 React 源碼的第二篇文章,如果你沒有閱讀過之前的文章,請(qǐng)務(wù)必先閱讀一下 第一篇文章 中提到的一些注意事項(xiàng),能幫助你更好地閱讀源碼。 文章相關(guān)資料 React ...

    hiYoHoo 評(píng)論0 收藏0
  • 剖析 React 源碼:render 流程(二)

    摘要:就是,如果你不了解這個(gè)的話可以閱讀下相關(guān)文檔,是應(yīng)用初始化時(shí)就會(huì)生成的一個(gè)變量,值也是,并且這個(gè)值不會(huì)在后期再被改變。這是我的剖析 React 源碼的第三篇文章,如果你沒有閱讀過之前的文章,請(qǐng)務(wù)必先閱讀一下 第一篇文章 中提到的一些注意事項(xiàng),能幫助你更好地閱讀源碼。 文章相關(guān)資料 React 16.8.6 源碼中文注釋,這個(gè)鏈接是文章的核心,文中的具體代碼及代碼行數(shù)都是依托于這個(gè)倉(cāng)庫(kù) 熱身...

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

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

0條評(píng)論

閱讀需要支付1元查看
<