常規操作之非同步
來自專欄那些年我不清楚的問題
已知:文件 a.txt(內容b.txt)、b.txt(內容c.txt)、c.txt(內容hello world)三個文件
目的:通過先讀取文件 a.txt 最終得到文件 c.txt 中的內容
注意:請自帶基礎閱讀,具體可以參考阮一峰老師的書籍。清楚非同步的發展和不同方法的適用場景以及實現原理才是最重要的,而不僅僅是使用(以下僅僅是使用)。
一、回調地域
let fs = require(fs);function read(url) { fs.readFile(url, utf-8, (err, data) => { if (err) throw err; // 先找 a.txt 中的內容得到字元串 b.txt fs.readFile(data, utf-8, (err, data) => { if (err) throw err; // 再找 b.txt 中的內容得到字元串 c.txt fs.readFile(data, utf-8, (err, data) => { if (err) throw err; // 終於得到 c.txt 中的內容啦 console.log(data); }); }); });}read(./a.txt);
二、Promise
let fs = require(fs);function read(url) { return new Promise((resolve, reject) => { fs.readFile(url, utf-8, (err, data) => { if (err) return reject(err); resolve(data); }); });}read(./a.txt).then(data => { // data => b.txt return read(data);}).then(data => { // data => c.txt return read(data);}).then(data => { // data => hi,終於找到我啦 ~ console.log(data);});
三、Generator + Promise
let fs = require(fs);function read(url) { return new Promise((resolve, reject) => { fs.readFile(url, utf-8, (err, data) => { if (err) return reject(err); resolve(data); }); });}function *gen(url) { return yield read(yield read(yield read(url)));}// generator返回的是一個迭代器let iterator = gen(./a.txt);iterator.next().value.then(data => { return iterator.next(data).value;}).then(data => { return iterator.next(data).value;}).then(data => { console.log(data);});
四、Generator + Promise + co
co 是 tj 寫的 JS 非同步解決方案的庫,其中有一個功能是可以自動執行 Generator 函數
let fs = require(fs);function read(url) { return new Promise((resolve, reject) => { fs.readFile(url, utf-8, (err, data) => { if (err) return reject(err); resolve(data); }); });}let co = require(co);// 也可以簡單模擬下 co 自動執行 Generator 函數這個功能// function co(it) {// return new Promise((resolve, reject) => {// function next(data) {// let { value, done } = it.next(data);// if (done) {// resolve(value);// } else {// value.then(data => {// // 第一次next傳參沒意義,也沒啥影響,第一個promise執行完再執行下一個// next(data);// }, reject);// }// }// next();// });// }co(function* () { console.log(yield read(yield read(yield read(./a.txt))));});
五、async/await
let fs = require(fs);function read(url) { return new Promise((resolve, reject) => { fs.readFile(url, utf-8, (err, data) => { if (err) return reject(err); resolve(data); }); });}// async 返回的是一個promise,await 後跟的也是一個 promiseasync function r() { return await read(await read(await read(./a.txt)));}r().then(data => { console.log(data);});// 當然也可以用co// let co = require(co);// co(r()).then(data => {// console.log(data);// });
題圖來源:危險
推薦閱讀: