Лекция 03
console.log('job started');
let r = xyz();
console.log('result: ' + r);
console.log('job done');
function xyz() {
// подготавливаем ответ
return 42;
}
console.log('job started');
xyz((r) => {
console.log('result: ' + r);
console.log('job done');
});
console.log('job in progress');
function xyz(cb) {
// подготавливаем ответ
setTimeout(() => { cb(42); }, 10);
}
// on click
let data = readFromDb();
function readFromDb() {
// читаем долго из БД
return data;
}
// on click
let data = [];
let t = new Thread(readFromDb, data);
function readFromDb(data) {
// читаем долго из БД
// заполняем массив data
}
// on click
let data = [];
readFromDb((result) => {
// заполняем массив data из result
});
function readFromDb(cb) {
// читаем долго из БД
cb(data);
}
let forEach = function (items, algo) {
for (let i = 0; i < items.length; i++) {
algo(items[i]);
}
};
let print = function (item) {
console.log(item);
};
let send = function (item) {
item.sendEmail();
};
let clients = [
{ email: 'jonhdoe@gmail.com',
sendEmail: () => {} },
{ email: 'mrsmith@gmail.com',
sendEmail: () => {} }
];
// выводим клиентов
forEach(clients, print);
// отправляем им email
forEach(clients, send);
function callback(error, data) {
if (error) {
// обрабатываем ошибку
} else {
// обрабатываем данные
}
}
fs.readdir(dir, (err, files) => {
if (err) { ... }
files.forEach((name) => {
if (!isImage(name)) return;
fs.readFile(name, (err, image) => {
if (err) { ... }
compress(image, (err, comp) => {
fs.writeFile(name, comp, (err) =>{
if (err) { ... }
else { ... }
});
});
});
});
});
1. Разбивайте на функции
fs.readdir(dir, processFiles);
1. Разбивайте на функции
function processFiles(err, files) {
if (err) { ... }
files.forEach(checkFile);
}
1. Разбивайте на функции
function checkFile(name) {
if (!isImage(name)) return;
fs.readFile(name, compressImage(name));
}
1. Разбивайте на функции
function compressImage(name) {
return (err, image) => {
if (err) { ... }
compress(file, rewriteImage(name));
}
}
1. Разбивайте на функции
function rewriteImage(name) {
return (err, image) => {
fs.writeFile(name, image, finishCompress);
}
}
1. Разбивайте на функции
function finishCompress(err) {
if (err) { ... }
else { ... }
}
function processFiles(err, files) {
if (err) { ... }
files.forEach(checkFile);
}
function checkFile(name) {
if (!isImage(name)) return;
fs.readFile(name, compressImage(name));
}
function compressImage(name) {
return (err, image) => {
if (err) { ... }
compress(file, rewriteImage(name));
}
}
function rewriteImage(name) {
return (err, image) => {
fs.writeFile(name, image, finishCompress);
}
}
function finishCompress(err) {
if (err) { ... }
else { ... }
}
fs.readdir(dir, processFiles);
2. Разбивайте на модули
...
function readDir(dir) {
fs.readdir(dir, processFiles);
}
module.export = readDir;
const compressImagesDir
= require('./compressImagesDir');
compressImagesDir('/tmp/images');
let news = {
subs: [],
onAdd: (cb) => {
news.subs.push(cb);
},
add: (item) => {
for (let i = 0; i < news.subs.length; i++)
news.subs[i](item);
}
};
news.onAdd((item) => {
console.log('CB#1:' + item);
});
news.onAdd((item) => {
console.log('CB#2:' + item);
});
news.add('hot news!');
/*
CB#1:hot news!
CB#2:hot news!
*/
function Bus () {
let self = this;
self.events = {};
self.on = (event, cb) => {
if (!self.events[event])
self.events[event] = [];
self.events[event].push(cb);
};
...
}
function Bus () {
...
self.emit = (event, data) => {
if (!self.events[event]) return;
let cbs = self.events[event];
for (let i = 0; i < cbs.length; i++)
cbs[i](data);
};
}
let bus = new Bus();
bus.on('newsAdded', (item) => {
console.log('CB#1:' + item);
});
bus.on('newsAdded', (item) => {
console.log('CB#2:' + item);
});
bus.on('xyz', (data) => { console.log(data); });
bus.emit('newsAdded', 'hot news!');
/*
CB#1:hot news!
CB#2:hot news!
*/
function zipDir(dir) {
return new Promise((resolve, reject) => {
// архивируем директорию
resolve(files);
});
};
zipDir('/tmp/images')
.then((files) => {
// обрабатываем файлы
});
function zipDir(dir) {
return new Promise((resolve, reject) => {
// что-то пошло не так
reject(err);
});
};
zipDir('/tmp/images')
.then((files) => { ... })
.catch((err) => {
// обрабатываем ошибку
});
function zipDir(dir) {
return new Promise((resolve, reject) => {
// что-то пошло не так
reject(err);
});
};
zipDir('/tmp/images')
.then((files) => { ... }, (err) => { ... });
// Deffered Object
function zipDir(dir) {
return new Promise((resolve, reject) => {
// Future
resolve(files);
});
};
// Promise
let p = zipDir('/tmp/images');
p.then((files) => { ... }, (err) => { ... });
function resolver(resolve, reject) {
return (err, data) => {
if (err) reject(err);
else resolve(data);
}
}
function readDir(dir) {
return new Promise((res, rej) => {
fs.readir(dir, resolver(res, rej));
});
}
function readDir(dir) {
return new Promise((res, rej) => {
// читаем файлы из папки
});
}
function zip(files) {
return new Promise((res, rej) => {
// архивируем файлы
});
}
function sendByEmail(file) {
return new Promise((res, rej) => {
// отправляем файл по email
});
}
readDir('/tmp/images')
.then((files) => { return zip(files) })
.then((file) => { return sendByEmail(file) })
.then(() => { ... })
.catch((err) => { ... });
readDir('/tmp/images')
.then((files) => { return zip(files) })
.then((file) => {
return Promise.all([
sendByEmail(user.email, file),
sendByEmail(admin.email, file)
]);
})
// results - массив с данными от промиссов
.then((results) => { ... })
.catch((err) => { ... });
readDir('/tmp/images')
.then((files) => { return zip(files) })
.then((file) => {
return Promise.race([
sendByEmail(user.email[0], file),
sendByEmail(user.email[1], file)
]);
})
// result - данные от выполненного промиса
.then((result) => { ... })
.catch((err) => { ... });
const a = new Promise(...);
a.then((data) => ..., (error) => ...);
!=
a.then(...).catch(...);
const a = new Promise(...);
a.then(...);
a.then(...);
!=
a.then(...).then(...);
const a = new Promise(...);
a.then(...)
.catch(...)
.then(...)
.catch(...);
http://bluebirdjs.com/
npm install bluebird
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync('hero.txt', 'utf-8')
.then((content) => console.log(content));
readDir('/tmp/images')
.then((files) => { return zip(files) })
.then((file) => {
return Promise.all([
sendByEmail(user.email, file),
sendByEmail(admin.email, file)
]);
})
.spread((result1, result2) => { ... })
.catch((err) => { ... });
function downloadS3Directory(from, to) {
return getS3DirectoryFiles(from)
.then(names =>
Promise.map(names, downloadS3File);
)
.then(files => files.map((file) => {
file.name = file.name.replace(from, '');
file.name = path.join(to, file.name);
return file;
}))
.then(files =>
Promise.mapSeries(files, saveFile)
);
}
Promise.some([
ping("ns1.example.com"),
ping("ns2.example.com"),
ping("ns3.example.com"),
ping("ns4.example.com")
], 2).then(pingArray => {
console.log('OK');
});
Promise.any([
ping("ns1.example.com"),
ping("ns2.example.com"),
ping("ns3.example.com"),
ping("ns4.example.com")
]).then(ping => {
console.log('OK');
});
readDir('/tmp/images')
.then((files) => { return zip(files) })
.then((file) => {
return Promise.all([
sendByEmail(user.email, file),
sendByEmail(admin.email, file)
]);
})
// .then([result1, result2]) => { ... })
.spread((result1, result2) => { ... })
.catch((err) => { ... });
async function read() {
let content = await
fs.readFileAsync('hero.txt', 'utf-8');
console.log(content);
};
read();
async function magic() {
try {
const files = await readDir('/tmp/images');
const archive = await zip(files);
await Promise.all([
sendByEmail(user.email, file),
sendByEmail(admin.email, file)
]);
...
} catch (error) {
...
}
}
(async function () {
...
})();
http://babeljs.io/
npm install --save-dev babel-core
npm install --save-dev babel-preset-es-2017
npm install --save babel-polyfill
https://babeljs.io/repl/
.babelrc
{
"presets": ["es-2017"]
}
babel.js
const fs = require('fs');
require("babel-core")
.transformFile('index.js', (err, result) => {
let code = 'require("babel-polyfill");\n'
+ result.code;
fs.writeFile('index.es5.js', code);
});
index.es5.js