<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                >[success] # 異步執行器 ~~~ 1.利用迭代器和生成器配合,做一個異步調用解決回調嵌套問題 ~~~ >[info] ## 需要知道的知識 ~~~ 1.生成器調用next 方法時候是可以傳值,注意第一次調用next 方法無論傳入什么參數都會被丟棄 next 傳入的參數是替代上一次yield 的返回值 ,第一次執行next 前不會有任何yield 語句 2.每次執行是以yield 作為執行的分界點 ~~~ >[danger] ##### 案例 ~~~ function *test(){ const data = yield 1 console.log(data,10000); const data1 = yield 2 console.log(data1,10000); } const g = test() // 執行順序: yield 1 console.log( g.next()) // 執行順序 :const data =》 console.log(data,10000)=》 yield 2 // 傳參的解釋 :此時next傳入參數100 方法的參數會替代上一次yield 返回值 即data 變成100 console.log( g.next(100)) // 執行順序 :const data1 =》 console.log(data1,10000) // 傳參的解釋 :此時next傳入參數300 方法的參數會替代上一次yield 返回值 即data 變成300 console.log( g.next(300)) // 打印結果 { value: 1, done: false } 100 10000 { value: 2, done: false } 300 10000 { value: undefined, done: true } ~~~ * 不傳值打印 ~~~ 1.因為沒有傳值 所以替代變成了undefined ~~~ ~~~ function *test(){ const data = yield 1 console.log(data,10000); } const g = test() console.log( g.next()) console.log( g.next()) // 打印結果 { value: 1, done: false } undefined 10000 { value: undefined, done: true } ~~~ >[info] ## 思考模型 async 和 await ~~~ 1.下面的例子只是一個猜想并不是能運行的案例 async function a(){ const datac = await c() console.log(datac); } const ia = a() ia.next() // 第一次next 執行 await c() 此時得到返回值 // 假如await c()返回值為100我們通過next傳入替代上一次datac值 // 變相我們打印datac 結果100 幫我們將這個異步過程同步 ia.next(100) ~~~ >[info] ## 利用迭代器生成器 實現思考模型中的async 和await ~~~ 1.現在有一個設想需要每一秒后打印10的遞加,例如 1s 時候輸出10 ,2s 時候輸出20 ~~~ >[danger] ##### 最簡單的方法 ~~~ 1.下面的方法形成嵌套,如果層級變多 不容易方便閱讀 ~~~ ~~~ setTimeout(()=>{ console.log(10); setTimeout(()=>{ console.log(20); },1000) },1000) ~~~ >[danger] ##### 使用了async 和await ~~~ function nn (data){ return new Promise((res)=>{ setTimeout(()=>{ res(data) },1000) }) } async function test(){ const res = await nn(10) console.log(res); const res1 = await nn(20) console.log(res1); } test() ~~~ >[danger] ##### 思考使用迭代器和生成器創造一個上面類似實現模型 ~~~ 1.需要知道什么是thunk 函數,接收一定的參數,會生產出定制化的函數,最后使用定制化的函數去完成 想要實現的功能 ~~~ * 先看一個簡單過渡案例 ~~~ function *gen(){ yield 1 yield ()=>{} } const g = gen(); console.log(g.next()); console.log(g.next()); // 打印結果 // { value: 1, done: false } // { value: [Function (anonymous)], done: false } ~~~ ~~~ // 創建一個thunk 函數 function fetchData(){ return (callback)=> { setTimeout(()=>{ callback(null) },1000) } } function *gen(){ const data = yield fetchData() console.log(data); const data1 = yield fetchData() console.log(data1); } const g = gen() // 此時 value 是一個函數 value() 調用這個函數 // 并且改函數 的參數是一個回調,我們利用next 傳參 // 可以接受上次yield 的返回值形 g.next().value(()=>{ g.next(10).value(()=>{ g.next(20) }) }) ~~~ * 抽象成遞歸 ~~~ 1.在使用的時候gen方法里面不用在形成回調地獄,可以更好的按順序去理解程序的執行 順序,最后只要執行run 方法自然幫我們執行遞歸的迭代器的調用 ~~~ ~~~ // 創建一個thunk 函數 function fetchData(){ return (callback)=> { setTimeout(()=>{ callback(null) },1000) } } function *gen(){ const data = yield fetchData() console.log(data); const data1 = yield fetchData() console.log(data1); } // 抽離成遞歸 function run(g){ // 迭代器next 返回值結構{value:'',done:Boolean} const next = () => { let data = 0 data += 10 let res = g.next(data); if(res.done) return; res.value(next); } next(); } const g =gen() run(g) ~~~ >[info] ##### node.js readFile 利用這種形式改造 >[danger] ##### 沒有改造的寫法 ~~~ 1.形成嵌套 ~~~ ~~~ // nodejs 讀取文件 // 這種就會形成 地獄嵌套 不停回調 fs.readFile('config.js', (err, data) => { if(err){ throw err; } // 操作data 例如需要data 在doSomethingWith 函數中操作 doSomethingWith(data) // 或者需要接著讀其他文件操作 fs.readFile('config.js1',(err1,data1 )=>{ if(err1){ throw err1 } console.log(data,data1); }) }) ~~~ >[danger] ##### 改造后的寫法 ~~~ const readFileThunk = (filename) => { return (callback) => { fs.readFile(filename, callback); } } const gen = function* () { const data1 = yield readFileThunk('1.txt') console.log(data1.toString()) const data2 = yield readFileThunk('2.txt') console.log(data2.toString) } let g = gen(); g.next().value((err, data1) => { g.next(data1).value((err, data2) => { g.next(data2); }) }) // 遞歸 function run(gen){ const next = (err, data) => { let res = gen.next(data); if(res.done) return; res.value(next); } next(); } run(g); ~~~ >[danger] ##### Generator 和 Promise 結合 ~~~ // 最后包裝成 Promise 對象進行返回 const readFilePromise = (filename) => { return new Promise((resolve, reject) => { fs.readFile(filename, (err, data) => { if(err) { reject(err); }else { resolve(data); } }) }).then(res => res); } let g = gen(); // 這塊和上面 thunk 的方式一樣 const gen = function* () { const data1 = yield readFilePromise('1.txt') console.log(data1.toString()) const data2 = yield readFilePromise('2.txt') console.log(data2.toString) } // 這塊和上面 thunk 的方式一樣 function run(gen){ const next = (err, data) => { let res = gen.next(data); if(res.done) return; // 此時value 是一個promise 對象 res.value.then(next); } next(); } run(g); ~~~ >[danger] ##### 有了asyn awiter ~~~ 1.有了asyn awiter 就不用需要自己創建遞歸執行 方法了,可以簡單看成Generator 的 * 號換成了 async,把 yield 換成了 awai ~~~ ~~~ // readFilePromise 依舊返回 Promise 對象 const readFilePromise = (filename) => { return new Promise((resolve, reject) => { fs.readFile(filename, (err, data) => { if(err) { reject(err); }else { resolve(data); } }) }).then(res => res); } // 這里把 Generator的 * 換成 async,把 yield 換成 await const gen = async function() { const data1 = await readFilePromise('1.txt') console.log(data1.toString()) const data2 = await readFilePromise('2.txt') console.log(data2.toString) } ~~~ >[info] ## 整體演變過程 ~~~ // 模擬數據請求 const query = (interval) => { return new Promise((resolve) => { setTimeout(() => { resolve(interval) }, interval) }) } // 方案一:基于PROMISE中的THEN鏈實現串行即可 query(1000) .then((result) => { console.log(`第一個請求成功:${result}`) return query(2000) }) .then((result) => { console.log(`第二個請求成功:${result}`) return query(3000) }) .then((result) => { console.log(`第三個請求成功:${result}`) }) // 方案二:基于generator處理 function* generator() { let result = yield query(1000) console.log(`第一個請求成功:${result}`) result = yield query(2000) console.log(`第二個請求成功:${result}`) result = yield query(3000) console.log(`第三個請求成功:${result}`) } let itor = generator() itor.next().value.then((result) => { itor.next(result).value.then((result) => { itor.next(result).value.then((result) => { itor.next(result) }) }) }) // 幫助我們把GENERATOR函數中的內容一點點去迭代執行 將上面具體化封裝以下 const isPromise = function isPromise(x) { if (x !== null && /^(object|function)$/i.test(typeof x)) { if (typeof x.then === 'function') { return true } } return false } const AsyncFunction = function AsyncFunction(generator, ...params) { return new Promise(function (resolve, reject) { let itor = generator(...params) const next = (x) => { let { done, value } = itor.next(x) if (done) { resolve(value) return } if (!isPromise(value)) value = Promise.resolve(value) value.then( (result) => next(result), (reason) => reject(reason) ) } next() }) } AsyncFunction(function* generator() { let result = yield query(1000) console.log(`第一個請求成功:${result}`) result = yield query(2000) console.log(`第二個請求成功:${result}`) result = yield query(3000) console.log(`第三個請求成功:${result}`) }) .then(() => { // GENERATOR函數中的內容全部正常執行完「例如:所有請求都成功」 console.log('都成功了!!') }) .catch((reason) => { // GENERATOR函數執行中出現問題「例如某個請求失敗」,則直接結束即可 console.log('請求失敗', reason) }) // 方案三:AWAIT 就是GENERATOR+PROMISE的語法糖 ;(async function () { let result = await query(1000) console.log(`第一個請求成功:${result}`) result = await query(2000) console.log(`第二個請求成功:${result}`) result = await query(3000) console.log(`第三個請求成功:${result}`) })() ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看