Open zhaoyan1986 opened 8 years ago
var path = require('path');
var fs = require('fs');
var request = require('request');
var express = require("express");
var __dirUrl = __dirname + '/views/pages/';
var port = process.env.PORT || 8080; //端口号
var app = express(); // 创建项目实例
app.set('views', __dirUrl);// 设置模板引擎
app.set('view engine', 'html');// 设置模板相对路径(相对当前目录)
app.use(express.static(path.join(__dirname, 'static'))); //静态资源
//创建服务器
app.listen(port);
/**
* 闲来,瞎搞。。。
var promiseHandlder = function (fn, receiver){
return function (){
var _args = Array.prototype.slice.call(arguments);
return new Promise(function(resolve, reject) {
var _newData = _args.concat(function (err, res){
return err ? reject(err) : resolve(res && res.toString());
});
return fn.apply(receiver, _newData);
});
};
};
promiseHandlder(fs.writeFile, fs)(__dirUrl + 'demo-1.text', "Hello World")
.then(function (){
console.log('writeFile success');
})
.then(function() {
return promiseHandlder(fs.appendFile, fs)(__dirUrl + 'demo-1.text', '\nsecond line');
}).then(function (){
console.log('appendFile success');
})
.then(function() {
return promiseHandlder(fs.readFile, fs)(__dirUrl + 'demo-1.text');
}).then(function (data){
console.log(data);
})
.catch(function(err) {
cosnole.log(err);
});
*/
/**
* 闲来,瞎搞。。。
*/
var promiseHandlder = function (fn, receiver, str, count){
this.fn = fn,
this.receiver = receiver;
this.str = str || '';
this.count = count || '';
this.__utilsType();
};
promiseHandlder.prototype = {
promisify: function (){
var self = this;
var _args = Array.prototype.slice.call(arguments);
_args = (this.isEmptyObject(arguments)) ? [this.str, this.count] : (this.utilsType.isArray(_args[0]) ? _args[0]: _args);
return new Promise(function(resolve, reject) {
var _newData = _args.concat(function (err, res){
return err ? reject(err) : resolve(res && res.toString());
});
return self.fn.apply(self.receiver, _newData);
});
},
appendFile: function () {
var args = Array.prototype.slice.call(arguments),
_cont = this.isEmptyObject(args) ? this.cont : args;
this.fn = this.receiver.appendFile;
return this.promisify(_cont);
},
readFile: function (){
var args = Array.prototype.slice.call(arguments),
_cont = this.isEmptyObject(args) ? this.str : args;
this.fn = this.receiver.readFile;
return this.promisify(_cont);
},
isEmptyObject: function (obj){
var key;
for(key in obj){
if(obj[key]){
return !1;
}
}
return !0;
},
utilsType: {},
/**
* __utilsType 保存所有的类型,并且判断是否是自己想要的类型
* @param utilsType 把对象保存在utilsType对象中。
* @param isArray: function (){}....
*/
__utilsType: function () {
var self = this,
i = 0,
typeArr = ['Array', 'Object', 'Null', 'undefined', 'Function'],
typeLen = typeArr.length;
for(; i < typeLen; i++ ){
(function (index) {
self.utilsType['is'+typeArr[index]] = function (info){
return Object.prototype.toString.call(info) == '[object '+ typeArr[index] +']';
};
})(i);
};
return this;
}
};
var _objPromise = new promiseHandlder(fs.writeFile, fs, __dirUrl + 'demo-1.text', "Hello World");
_objPromise.promisify()
.then(function (){
console.log('writeFile success');
})
.then(_objPromise.appendFile(__dirUrl + 'demo-1.text', "Hello World111111"))
.then(function (){
console.log('appendFile success');
})
/**
* 两种调方式都是可以的,下面也可行
*
.then(function (){
return _objPromise.readFile();
})
*/
.then(_objPromise.readFile.bind(_objPromise))
.then(function (data){
console.log(data);
})
.catch(function(e) {
cosnole.log(e.message);
});
/**
* http 请求 - Promise
*/
var promise_request = function (url, id) {
this.url = url || '';
this.id = id || '_id';
};
promise_request.prototype = {
getInfo: function () {
var self = this;
return new Promise(function (resolve, reject) {
return request(self.url, function (err, response, data) {
if(!err && (response.statusCode >= 200 && response.statusCode < 300 || response.statusCode == 304)){
resolve(data);
}else{
reject(err);
}
});
});
},
readJSON: function (params) {
return this.getInfo().then(JSON.parse);
},
getUserId: function () {
var self = this;
return this.readJSON().then(function (data) {
return data[self.id];
});
}
};
/**
* 获取用户ID http://demos.so/result/homework.promise.userInfo
* 用户发布过的帖子api地址 'http://demos.so/result/userid='+id
* 用户学习过的帖子API地址 'http://demos.so/result/student='+id
*/
var req_str = {
getUserId: function () {
return new promise_request('http://demos.so/result/homework.promise.userInfo').getUserId().then();
},
post_t: function () {
return this.getUserId().then(function (data){
return new promise_request('http://demos.so/result/userid=' + data).getInfo().then(JSON.parse);
});
},
study_t: function () {
return this.getUserId().then(function (data){
return new promise_request('http://demos.so/result/student=' + data).getInfo().then(JSON.parse);
});
},
main: function (time){
return Promise.all([this.post_t(), this.study_t()]);
},
race: function (time){
return Promise.race([this.post_t(), this.study_t(), this.timeout(time)]);
},
timeout: function (time){
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
reject('请求超时了');
}, time);
});
return promise;
}
};
/**
* main 里面封装的all,
* 两次贴子的进程同时发出,并返回相对应的结果
req_str.main().then(function (value){
console.log('用户发布过的帖子----------------------------');
console.dir(value[0]);
console.log('------------------------------------------');
console.log('用户学习过的帖子----------------------------');
console.dir(value[1]);
}, function (err){
console.log(err);
}).catch(function (err){
console.log(err);
});
*/
/**
* 使用race 传入时间来控制超时
* 测试
*/
req_str.race(1000).then(function (value){
console.log('谁快就显示谁喽----------------------------');
console.log(value);
console.log('------------------------------------------');
}, function (err){
console.log(err);
}).catch(function (err){
console.log(err);
});
//404
app.use(function (req, res, next){
res.status(404).send('Sorry, we cannot find that!');
//next();
});
//500
app.use(function(err, req, res, next){
res.status(500).send({ error: 'something blew up' });
//next();
});
'use strict'
var fs = require('fs');
let getPromise = callback => {
return new Promise((resolve, reject) => {
callback(resolve, reject)
})
}
// 读写插入文件
getPromise((resolve, reject) => {
fs.writeFile('123.txt', 'hello world', (err) => {
if (err) reject(err)
console.log('写入成功')
resolve()
})
}).then(getPromise((resolve, reject) => {
fs.appendFile('123.txt', ' dashixiong', (err) => {
if (err) reject(err)
console.log('插入成功');
resolve()
})
})).then((data) => {
fs.readFile('123.txt', 'UTF-8', (err, data) => {
if (err) reject(err)
console.log(data)
})
}).catch((error) => {
console.log(error)
})
// 并行请求
let http = require('http');
let getRequestPromise = (url, callback) => {
return getPromise((resolve, reject) => {
http.request(url, (res) => {
let data = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
data = JSON.parse(data);
callback(resolve, reject, data);
})
}).on('error', function(error) {
reject(error)
}).end();
})
};
const idUrl = 'http://demos.so/result/homework.promise.userInfo';
getRequestPromise(idUrl, (resolve, reject, data) => {
resolve(data._id);
}).then((data) => {
const postUrl = `http://demos.so/result/userid=${data}`,
learnUrl = `http://demos.so/result/student=${data}`;
return Promise.all([
getRequestPromise(postUrl, (resolve, reject, data) => {
resolve(data);
}),
getRequestPromise(learnUrl, (resolve, reject, data) => {
resolve(data);
})
])
}).then(function(datas) {
console.log(datas)
})
//超时
let xhr = null;
let getXHRPromise = (url) => {
return getPromise((resolve, reject) => {
xhr = new XMLHttpRequest();
console.log(xhr)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
resolve()
} else {
reject('xhr')
}
}
};
xhr.open('get', url, true);
xhr.send(null);
})
}
let timeout = (time, promise) => {
Promise.race([
getPromise((resolve, reject) => {
setTimeout(() => {
reject(new Error('timeout'))
}, time)
}),
promise
]).catch((error) => {
if (error.message == 'timeout') {
console.log('timeout')
xhr.abort()
}
})
}
timeout(1000, getXHRPromise())
var Promise = require("promise"),
fs = require("fs"),
request = require("request");
// hw1
var PromiseWrapper = function(fn) {
return function() { // 使用...args报错
var args = Array.prototype.slice.call(arguments);
return new Promise(function(resolve, reject) {
args.push(function(err, data) {
if (err) {
reject(err);
} else {
if (data) {
console.log(data.toString());
}
resolve(data);
}
});
fn.apply(fs, args);
});
}
};
PromiseWrapper(fs.writeFile)("test.txt", "Hello World")
.then(function() {
PromiseWrapper(fs.appendFile)("test.txt", "\nHello Again");
})
.then(function() {
PromiseWrapper(fs.readFile)("test.txt");
})
.catch(function(err) {
cosnole.log(err);
});
// hw2
var promiseAjax = function(url) {
return new Promise(function(resolve, reject) {
request(url, function(err, res, body) {
if (!err && res.statusCode == 200) {
resolve(body);
} else {
reject(err, res.statusCode);
}
});
});
}
promiseAjax("http://demos.so/result/homework.promise.userInfo")
.then(function(body) {
var res = body;
res = JSON.parse(res);
return Promise.all([promiseAjax("http://demos.so/result/userid=" + res._id), promiseAjax("http://demos.so/result/student=" + res._id)]);
})
.then(function(arr) {
console.log("hw2", arr);
})
.catch(function(err) {
console.log(err);
});
// extra
function timeout(time) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject("timeout");
}, time);
});
}
promiseAjax("http://demos.so/result/homework.promise.userInfo")
.then(function(body) {
var res = body;
res = JSON.parse(res);
var success = Promise.all([promiseAjax("http://demos.so/result/userid=" + res._id), promiseAjax("http://demos.so/result/student=" + res._id)]);
var fail = timeout(1);
return Promise.race([success, fail]);
})
.then(function(arr) {
console.log(arr);
})
.catch(function(err) {
console.log(err);
});
/* log.js */
"use strict";
import path from "path";
import fs from "fs";
import chalk from "chalk";
import moment from "moment";
const logPath = path.resolve(path.dirname(__dirname), "log");
const logStyle = {
"success": "green",
"warn": "red",
"default": "green"
};
/**
*
* @param filename
* @param data
*/
function writeLog(filename, data) {
let fileFullPath = path.join(logPath, filename);
fs.exists(fileFullPath, err => {
if (err) {
fs.appendFile(fileFullPath, data);
}
else {
fs.writeFile(fileFullPath, data);
}
});
}
/**
*
* @param type
*/
function output(type) {
let style = logStyle[type] || logStyle.default;
if (typeof chalk[style] !== "function") {
style = "green";
}
console.log.apply(console, Array.prototype.slice.call(arguments, 1).map(item => {
return chalk[style](JSON.stringify(item));
}));
writeLog(`${moment().format("L").replace(/\//ig, "-")}.${type}.log`, Array.prototype.slice.call(arguments, 1).map(item => {
return JSON.stringify(item);
}).join("\t") + "\n");
}
/**
* @param arguments
*/
function successLog() {
output.apply(null, ["success", moment().format()].concat(Array.prototype.slice.call(arguments, 0)));
}
/**
* @param arguments
*/
function warnLog() {
output.apply(null, ["warn", moment().format()].concat(Array.prototype.slice.call(arguments, 0)));
}
module.exports = {output, successLog, warnLog};
/* spider.js */
"use strict";
import request from "request";
import Promise from "promise";
import EventEmitter from "events";
import fs from "fs";
import path from "path";
import cheerio from "cheerio";
import {exec} from "shelljs";
import {successLog, warnLog} from "./log";
/**
* 数据存储路径
* @type {string}
*/
const dataPath = path.resolve(path.dirname(__dirname), "data");
/**
*
* @param url
* @returns {*}
*/
function crawleWebpage(url) {
return new Promise((resolve, reject) => {
request.get(url, {encoding: "utf8"}, (err, req, body) => {
if (err) {
reject(err);
}
else {
resolve(body);
}
});
});
}
/**
*
* @param content
* @param filter
* @returns {*}
*/
function convertWebpage(content, filter) {
let $ = cheerio.load(content, {decodeEntities: false});
$(filter.orgin).text(filter.target);
return $.html();
}
/**
*
* @param key
* @param filedata
* @returns {*}
*/
function saveToLocal(filepath, filedata) {
return new Promise((resolve, reject) => {
fs.writeFile(filepath, filedata, err => {
if (err) {
reject(err);
}
else {
resolve(filepath);
}
});
});
}
/**
*
* @param key
* @returns {*}
*/
function generateLocalPath(key) {
return path.join(dataPath, key + "_" + new Date().getFullYear() + ".html");
}
/**
*
* @returns {*}
*/
function generateLogPath() {
return path.join(dataPath, new Date().getFullYear() + ".json");
}
export default class SpiderPromise extends EventEmitter {
/**
*
* @param conf
*/
constructor(conf) {
super();
this.conf = Object.assign({}, conf);
}
/**
*
* @param config
* @returns {*}
*/
excuteTask(config) {
return crawleWebpage(config.url)
.then(content => {
return convertWebpage(content, config.filter);
})
.then(filedata => {
return saveToLocal(generateLocalPath(config.key), filedata);
})
.then(filepath => {
config.filepath = filepath;
return config;
});
}
/**
* runTasks
*/
runTasks() {
let self = this;
successLog("spider任务开始");
return Promise.
all(this.conf.tasks.map(item => {
return self.excuteTask(item);
}))
.then(res => {
return saveToLocal(generateLogPath(), JSON.stringify(res));
})
.then(filepath => {
successLog("task run complete!");
exec("cat " + filepath);
})
.catch(err => {
warnLog("task run fail!");
warnLog(err);
})
.finally(() =>{
successLog("spider任务结束");
});
}
}
/* api.js */
"use strict";
import request from "request";
import Promise from "promise";
import EventEmitter from "events";
import {successLog, warnLog} from "./log";
/**
* 超时时间
* @type {number}
*/
const timeout = 3000;
/**
*
* @param timeout
* @returns {*}
*/
function timerDown(timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("已超时");
}, timeout);
});
}
/**
*
* @param url
* @returns {*}
*/
function get(url) {
return new Promise((resolve, reject) => {
request.get(url, {encoding: "utf8"}, (err, req, body) => {
if (err) {
reject(err);
}
else {
resolve(JSON.parse(body));
}
});
});
}
/**
*
* @param url
* @returns {*}
*/
function fecthData(url) {
return Promise.race([get(url), timerDown(timeout)]);
}
export default class ApiPromise extends EventEmitter {
/**
*
* @param conf
*/
constructor(conf) {
super(conf);
this.conf = Object.assign({}, conf);
}
/**
*
* @returns {*}
*/
fetchUserid() {
return fecthData(this.conf["getUserInfo"])
.then(res => {
return res["_id"];
});
}
/**
*
* @param id
* @returns {*}
*/
fetchPublicPost(id) {
return fecthData(this.conf["getPublicPostByUserid"].replace("{userid}", id));
}
/**
*
* @param id
* @returns {*}
*/
fetchStudyPost(id) {
return fecthData(this.conf["getStudyPostByUserid"].replace("{userid}", id));
}
/**
* runTasks
*/
runTasks() {
var self = this;
successLog("api任务开始");
return Promise
.all([
self.fetchUserid()
.then(this.fetchUserid.bind(this)),
self.fetchUserid()
.then(this.fetchStudyPost.bind(this))
])
.then(res => {
successLog("fetchPublicPost:", res[0]);
successLog("fetchStudyPost:", res[1]);
})
.catch(err => {
warnLog(err);
})
.finally(() => {
successLog("api任务结束");
});
}
}
/* sqliteDb.js */
"use strict";
import fs from "fs";
import path from "path";
import Promise from "promise";
import sqlite3 from "sqlite3";
/**
*
* @type {*}
*/
global.cache = Object.assign({}, global.cache);
/**
*
* @param filepath
* @returns {*}
*/
function checkDbfile(filepath) {
return new Promise((resolve, reject) => {
fs.exists(filepath, isExists => {
if (isExists) {
resolve(filepath);
}
else {
fs.writeFile(filepath, "", err => {
if (err) {
reject(err);
}
else {
resolve(filepath);
}
});
}
});
});
}
/**
*
* @param sqliteDb
* @param statement
*/
async function createTable(sqliteDb, statement) {
await sqliteDb.run(statement);
}
/**
*
* @param config
* @returns {*}
*/
async function getSqliteDb(config) {
let sqlite3Cls = config.debug ? sqlite3.verbose() : sqlite3,
dbpath = path.resolve(config.dbPath),
sqliteDb = global.cache[dbpath];
if (!sqliteDb) {
if (await checkDbfile(dbpath)) {
sqliteDb = new sqlite3Cls.Database(dbpath);
}
else {
throw new Error("can`t find" + dbpath);
}
}
await createTable(sqliteDb, config.tableStatement);
return global.cache[dbpath] = sqliteDb;
}
module.exports = {getSqliteDb};
/* analyzer.js*/
"use strict";
import EventEmitter from "events";
import fs from "fs";
import path from "path";
import Promise from "promise";
import {getSqliteDb} from "./sqliteDb";
/**
*
* @param dirPath
* @returns {*}
*/
function readDir(dirPath) {
return new Promise((resolve, reject) => {
fs.readdir(dirPath, (err, files) => {
if (err) {
reject(err);
}
else {
resolve(files.map(file=> {
return path.resolve(dirPath, file);
}));
}
});
});
}
/**
*
* @param filepath
* @returns {*}
*/
function readFile(filepath) {
return new Promise((resolve, reject) => {
fs.exists(filepath, isExists => {
if (isExists) {
fs.readFile(filepath, (err, content) => {
if (err) {
reject(err);
}
else {
resolve(content.toString());
}
});
}
else {
reject(`${filepath} not found\n`);
}
});
});
}
/**
*
* @param filePath
* @returns {*}
*/
function rmFile(filePath) {
return new Promise((resolve, reject) => {
fs.unlink(filePath, (err) => {
if (err) {
reject(err);
}
else {
resolve(true);
}
});
});
}
/**
*
* @param content
* @returns {*}
*/
function formatSql(content = "") {
return content.replace(/"/ig, "").split("\n").map(line => {
return line.split("\t");
});
}
/**
*
* @param db
* @param record
* @returns {*}
*/
function insertSingleRecord(db, tableName, record) {
return new Promise((resolve, reject) => {
db.run("INSERT INTO " + tableName + "(time, msg, content) VALUES (?, ?, ?);", Object.assign(["", "", ""], record), function(err){
if (err) {
reject(err);
}
else {
resolve(this.lastID);
}
});
});
}
/**
*
* @param db
* @param tableName
* @returns {Function}
*/
function genInsertSqlFunc(db, tableName) {
return function (records = []) {
return Promise.all(records.map(record => {
return insertSingleRecord(db, tableName, record);
}));
};
}
/**
*
* @param db
* @param tableName
* @param filePath
* @returns {*}
*/
function analysisFile(db, tableName, filePath) {
return readFile(filePath)
.then(formatSql)
.then(genInsertSqlFunc(db, tableName))
.then(res => {
rmFile(filePath);
return res;
});
}
/**
*
* @param db
* @param tableName
* @returns {Function}
*/
function genAllFilesAnalysisFunc(db, tableName) {
return function (files) {
return Promise.all(files.map((file => {
return analysisFile(db, tableName, file);
})));
};
}
export default class Analyzer extends EventEmitter {
/**
*
* @param conf
*/
constructor(conf) {
super();
this.conf = Object.assign({
"tableName": "log_record",
"tableStatement": "CREATE TABLE IF NOT EXISTS log_record (id INTEGER PRIMARY KEY AUTOINCREMENT, time CHAR(50) NOT NULL, msg CHAR(50) NOT NULL, content TEXT);",
"logPath": "./log",
"debug": false,
"dbPath": "./data/sqlite.db"
}, conf);
}
/**
*
* @returns {*}
*/
async runTasks() {
return readDir(path.resolve(this.conf["logPath"]))
.then(genAllFilesAnalysisFunc(await getSqliteDb(this.conf), this.conf["tableName"]))
.then(res => {
console.log(res);
});
}
}
/* 入口文件 index.js */
"use strict";
import SpiderPromise from "./spider";
import ApiPromise from "./api";
import Analyzer from "./analyzer";
import config from "../conf/source";
import apiConfig from "../conf/api";
function start(){
new SpiderPromise(config).runTasks();
new ApiPromise(apiConfig).runTasks();
new Analyzer().runTasks();
}
start();
import fs from 'fs';
/**
* promisify the callback function
* @param {Function} fn callback function
* @param {Object} receiver receiver
* @return {Function} promise function
*/
const promisify = (fn, receiver) => {
return (...args) => {
return new Promise((resolve, reject) => {
fn.apply(receiver, [...args, (err, res) => {
return err ? reject(err) : resolve(res);
}]);
});
};
};
const filepath = './promise.txt';
promisify(fs.writeFile, fs)(filepath, 'first line').then(() => {
console.log('writeFile success');
}).then(() => {
return promisify(fs.appendFile, fs)(filepath, '\nsecond line').then(() => {
console.log('appendFile success');
});
}).then(() => {
return promisify(fs.readFile, fs)(filepath, 'UTF-8').then(content => {
console.log('readFile success');
console.log(content);
});
}).catch(error => {
console.error(error);
});
/* wrap.js */
'use strict';
function wrap(fn, context) {
let args = [].slice.call(arguments, 2);
return new Promise ((resolve, reject) => {
args.push(function(error) {
error ? reject(error) : resolve.apply(null, [].slice.call(arguments, 1));
});
fn.apply(context, args);
});
}
module.exports = wrap;
/* 第一题 */
'use strict';
const fs = require('fs');
const os = require('os');
const path = require('path');
const wrap = require('./wrap');
const tmpFile = path.join(os.tmpdir(), 'promiseTmpFile');
wrap(fs.writeFile, fs, tmpFile, 'Hello ')
.then(() => wrap(fs.appendFile, fs, tmpFile, 'world!'))
.then(() => wrap(fs.readFile, fs, tmpFile))
.then(content => console.log(`File content: ${content}`))
.catch(error => console.log('io error!', error));
/* 第二题 */
'use strict';
const wrap = require('./wrap');
const request = require('request');
const getUserInfoAPI = 'http://demos.so/result/homework.promise.userInfo';
const getuserPublishAPI = 'http://demos.so/result/userid';
const getuserLearnAPI = 'http://demos.so/result/student';
const httpTimeout = 30;
const httpGet = function(url) {
let timer;
return Promise.race([
new Promise((_, reject) =>
timer = setTimeout(() => reject('request time out'), httpTimeout * 1000)
),
wrap(request, null, url).then(response => {
clearTimeout(timer);
return JSON.parse(response.body);
})
]);
};
httpGet(getUserInfoAPI)
.then(userInfo => Promise.all([
httpGet(`${getuserPublishAPI}=${userInfo._id}`),
httpGet(`${getuserLearnAPI}=${userInfo._id}`)
]))
.then(data => {
console.log('user published:', data[0].map(item => item.title).join('、'));
console.log('user learned:', data[1].map(item => item.title).join('、'));
})
.catch(error => console.log('network error:', error));
var Promise = require("promise");
var fs = require("fs");
var request = require("request");
const filename = "test.txt";
const userInfoUrl = "http://demos.so/result/homework.promise.userInfo";
const learnUrl = "http://demos.so/result/student=";
const postUrl = "http://demos.so/result/userid=";
/*作业一*/
function controlFile(filename,type,data) {
return new Promise((resolve,reject) => {
var readFile = (type == "readFile");
var controlType = (readFile ? "utf8" : data);
fs[type](filename,controlType,(err,data) => {
if (err) reject(err);
readFile && console.log(data);
resolve(data);
})
})
}
controlFile(filename,"writeFile","hello world")
.then(controlFile(filename,"appendFile"," again world"))
.then(controlFile(filename,"readFile"));
/*作业二*/
function promiseAjax(url) {
return new Promise(function(resolve,reject) {
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(JSON.parse(body));
} else {
reject(error);
}
})
})
}
function timeout(time) {
return new Promise(function(resolve,reject) {
setTimeout(function() {
reject("timeout");
},time);
});
}
promiseAjax(userInfoUrl)
.then(function(userInfo) {
var id = userInfo._id;
var getSuccess = Promise.all([promiseAjax(postUrl + id),promiseAjax(learnUrl + id)])
return Promise.race([getSuccess,timeout(1000)]);
})
.then(function(data) {
console.log(data);
},function(){
console.log("1111");
})
.catch(function(err) {
console.log(err);
})
/********************** 作业一 *************************/
var fs = require('fs');
function writeFile(){
return new Promise(function(resolve,reject){
var data = "写入数据到file.txt文件中";
fs.writeFile('file.txt',data,'utf-8',function(err){
if(err){
reject(new Error(err));
return;
}else{
resolve();
}
});
})
}
function appendFile(){
return new Promise(function(resolve,reject){
var data = "\n\n追加数据到file.txt文件中";
fs.appendFile('file.txt',data,'utf-8',function(err){
if(err){
reject(new Error(err));
return;
}else{
resolve();
}
})
});
}
function readFile(){
return new Promise(function(resolve,reject){
fs.readFile('file.txt','utf-8',function(err,data){
if(err){
reject(new Error(err));
}else{
console.log(data);
}
})
});
}
var promise = Promise.resolve();
promise.then(writeFile)
.then(appendFile)
.then(readFile)
.catch(function(error){
console.log("抛出异常:"+ error);
});
/********************** 作业二 *************************/
var request = require('request');
function requestFun(URL){
return new Promise(function (resolve, reject){
request(URL,function(error, response, data){
if (!error && response.statusCode == 200) {
resolve(data);
}else{
reject(error);
}
})
})
};
var reqInfo = {
getUserId: function () {
return requestFun('http://demos.so/result/homework.promise.userInfo').then(function(data){
return JSON.parse(data)['_id'];
})
},
getUserStudy : function(){
return this.getUserId().then(function(id){
return requestFun('http://demos.so/result/student='+ id).then(JSON.parse);
});
},
getUserIssue : function(){
return this.getUserId().then(function(id){
return requestFun('http://demos.so/result/userid='+ id).then(JSON.parse);
});
},
promiseAll : function(){
return Promise.all([this.getUserStudy(),this.getUserIssue()])
},
promiseRace : function(){
return Promise.race([this.getUserStudy(),this.getUserIssue(),this.reqTimeout()]);
},
reqTimeout : function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("您的请求超时了~~~~~~~~~~~~~~~~");
},200);
})
}
}
/**
promise.all
用户发布的帖子和用户学习帖子同时并行请求
*/
reqInfo.promiseAll().then(function(value){
console.log("\n\n\n\npromise.all:\n");
console.log("用户学习过的帖子:\n");
console.log(value[0]);
console.log("\n用户发布的帖子:\n");
console.log(value[1]);
},function(error){
console.log(error);
}).catch(function(error){
conosle.log(error);
})
/**
promise.race
用户发布的帖子和用户学习帖子同时并行请求
*/
reqInfo.promiseRace().then(function(value){
console.log("\n\n\n\npromise.race:\n");
console.log("请求快的先显示:");
console.log(value);
},function(error){
console.log(error);
}).catch(function(error){
conosle.log(error);
})
/*作业1*/
var fs = require('fs'),
promuse = Promise.resolve();
promuse.then(function(){
fs.writeFile('promise.txt','hello promise',(err) => {
if(err){
reject(new Error(err));
}
});
}).then(function(){
fs.appendFile('promise.txt',' data to appendFile',(err) => {
if(err){
reject(new Error(err));
}
});
}).then(function(){
fs.readFile('promise.txt','utf8',(err , data) => {
if(err){
reject(new Error(err));
}
console.log(data);
})
}).catch(function(error){
console.log(error);
});
/*作业2*/
var http = require('http'),
infoApi = 'http://demos.so/result/homework.promise.userInfo',
pubApi = 'http://demos.so/result/userid=',
learnApi = 'http://demos.so/result/student=';
function delayPromise(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
function timeoutPromise(promise, ms) {
var timeout = delayPromise(ms).then(function () {
throw new Error('超时' + ms + ' ms');
});
return Promise.race([promise, timeout]);
}
function getData(url) {
return new Promise(function(resolve,reject) {
http.request(url, (res) => {
var data;
res.setEncoding('utf8');
res.on('data', (chunk) => {
data = JSON.parse(chunk);
});
res.on('end', () => {
resolve(data);
})
}).on('error', function(error) {
reject(error)
}).end();
})
}
timeoutPromise(getData(infoApi),1000).then(function(data){
var id = data._id;
return Promise.all([timeoutPromise(getData(pubApi + id),1000),timeoutPromise(getData(learnApi + id),1000)]);
}).then(function(data){
console.log('发布的帖子')
console.log(data[0])
console.log('学习的帖子')
console.log(data[1])
}).catch(function(error){
console.log(error)
});
//fs 'use strict'; let fs = require('fs'), fileName = "file.txt", result = "";
new Promise((resolve, reject) => { let str = "随便写点什么"; fs.writeFile(fileName, str, resolve); }).then((err) => { return new Promise((resolve, reject) => { if(err){ reject(err); } var str2 = "随便追加点什么"; fs.appendFile(fileName, str2, resolve); }); }).then((err) => { return new Promise((resolve, reject) => { if(err){ reject(err); } fs.readFile(fileName, (err, data) => {resolve(data)}); }); }).then((data) => { return new Promise((resolve, reject) => { console.log(data.toString()); });
}).catch((err) => { console.log("err: " + err); })
//request let request = require('request'), getReqPromise = (url, timeout) => { return new Promise((resolve, reject) => { if(timeout){ setTimeout(() => { reject("timeout"); }, timeout); } request(url, function(err, response, body){ if(err){ reject(err); } else if(response.statusCode == 200){ let data = JSON.parse(body); resolve(data); } }); }); }, url1 = "http://demos.so/result/homework.promise.userInfo", url2 = "http://demos.so/result/userid=", url3 = "http://demos.so/result/student=";
getReqPromise(url1).then((data) => { let id = data['_id']; Promise.all([getReqPromise(url2 + id), getReqPromise(url3 + id)]).then((datas) =>{ console.log("发布的帖子:"); console.log(data[0]); console.log("学习的帖子:"); console.log(data[1]); }).catch((err) => { console.log("err: " + err); }); }).catch((err) => { console.log("err: " + err); });
module.exports = promisify
function promisify(fn) {
return wrapper(fn)
}
function createCallback(resolve, reject) {
return function(err, value) {
if (err) return reject(err)
var length = arguments.length
if (length <= 2) return resolve(value)
var values = new Array(length - 1)
for (var i = 1; i < length; ++i) values[i - 1] = arguments[i]
resolve(values)
}
}
function wrapper(fn) {
return (function() {
var self = this
var len = arguments.length
var args = new Array(len + 1)
for (var i = 0; i < len; ++i) args[i] = arguments[i]
var lastIndex = i
return new Promise(function (resolve, reject) {
args[lastIndex] = createCallback(resolve, reject)
fn.apply(self, args);
})
})
}
function PromisifyAll(source, destination, methods) {
return promisifyAll(source, destination, methods, promisify)
}
function promisifyAll(source, destination, methods, promisify) {
if (!destination) {
destination = {}
methods = Object.keys(source)
}
if (Array.isArray(destination)) {
methods = destination
destination = {}
}
if (!methods) {
methods = Object.keys(source)
}
if (typeof source === 'function') destination = promisify(source)
methods.forEach(function (name) {
if (typeof source[name] === 'function') destination[name] = promisify(source[name])
})
Object.keys(source).forEach(function (name) {
if (destination[name]) return
destination[name] = source[name]
})
return destination
}
/**
* 第一题
*/
var fs = PromisifyAll(require('fs'), {}, [
'readFile',
'writeFile',
'appendFile',
])
var readme = __dirname + '/README'
fs.writeFile(readme, 'Hello 小灶会\r\n')
.then(fs.appendFile(readme, '欢迎参加'))
.then(() => {
fs.readFile(readme).then(content => {
console.log(content.toString())
})
})
/* 第一题 */
var fs = require('fs');
var fileName = '1.txt';
var firstWrite = function () {
return new Promise(function (resolve, reject) {
var str = +new Date() + '\n';
fs.writeFile(fileName, str, function(err){
if(err) reject(err);
resolve();
})
})
}
var appendWrite = function () {
return new Promise(function (resolve, reject) {
var str = +new Date() + '\n';
fs.appendFile(fileName, str, function(err){
if(err) reject(err);
resolve();
})
})
}
var log = function () {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(err, data){
if(err) reject(err);
console.log(data.toString());
})
})
}
firstWrite().then(appendWrite).then(log).catch(function (err) {
console.log(err);
});
/* 第二题 */
var request = require('request');
var userApi = 'http://demos.so/result/homework.promise.userInfo',
demosApi = 'http://demos.so/result/';
var demosTypes = ['userid', 'student'];
var TIMEOUT = 1000;
var delayPromise = function (ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
})
};
var timeoutPromise = function(promise, ms) {
var timeout = delayPromise(ms).then(function() {
throw new Error('Operation timed out after' + ms + ' ms');
})
return Promise.race([promise, timeout]);
}
var getUserInfo = function () {
var task = new Promise(function (resolve, reject) {
request.get({url: userApi, json: true}, function (error, response, body) {
if(error) reject(err);
if(response.statusCode != 200) reject(response.statusCode);
resolve(body);
})
})
return timeoutPromise(task, TIMEOUT);
}
var getDemos = function (userInfo) {
return Promise.all(
demosTypes.map(function (type) {
var url = demosApi + type + '=' + userInfo._id;
var task = new Promise(function (resolve, reject) {
request.get({url, url, json: true}, function (error, response, body) {
if(error) reject(err);
if(response.statusCode != 200) reject(response.statusCode);
resolve(body);
})
})
return timeoutPromise(task, TIMEOUT);
})
)
}
getUserInfo().then(getDemos).then(function (data) {
console.log(data);
}).catch(function (err) {
console.log(err);
});
/* 1 */
var fs = require('fs');
new Promise((resolve, reject) => {
fs.writeFile('./1.txt', 'writeFile done', (err) => {
if(err) reject(err);
console.log('write success');
resolve();
})
}).then(() => {
return new Promise((resolve, reject) => {
fs.appendFile('./1.txt', '\nappendFiel done', (err) => {
if(err) reject(err);
console.log('append success');
resolve();
})
})
}).then(() => {
return new Promise((resolve, reject) => {
fs.readFile('./1.txt', 'utf-8', (err, data) => {
if(err) reject(err);
console.log(data);
resolve();
})
})
}).catch((err) => {
console.log('err', err);
})
/* 2 */
var request = require('request');
var userApi = 'http://demos.so/result/homework.promise.userInfo',
pubApi = 'http://demos.so/result/userid=',
studyApi = 'http://demos.so/result/student=',
timeout = 2;
var timeoutFun = function (promise, timeout) {
var t = new Promise(function (resolve, reject) {
setTimeout(resolve, timeout)
}).then(function () {
throw new Error ('operation timed out');
})
return Promise.race([promise, t]);
}
new Promise(function (resolve, reject) {
request.get({url: userApi, json: true}, function (err, response, body) {
if (err) reject(err);
resolve(body)
})
}).then(function (userInfo) {
return Promise.all([
timeoutFun(new Promise(function (resolve, reject) {
console.log('pubApi', pubApi + userInfo._id);
request.get({url: pubApi + userInfo._id, json: true}, function (error, reponse, body) {
if (error) reject(error);
resolve(body)
})
}), timeout),
timeoutFun(new Promise(function (resolve, reject) {
console.log('studyApi', studyApi + userInfo._id);
request.get({url: studyApi + userInfo._id, json: true}, function (error, reponse, body) {
if (error) reject(error);
resolve(body)
})
}), timeout)
])
}).then(function (datas) {
console.log(datas);
}).catch(function (err) {
console.log('err', err);
})
/*学习了大家的代码,新改了一份~~*/
/*第一题*/
var fs = require('fs');
function wrapper(fn,context) {
var args = Array.prototype.slice.call(arguments,2);
return new Promise((resolve,reject) => {
args.push((err,data) => {
err ? reject(err) : resolve(data);
});
fn.apply(context,args);
});
}
wrapper(fs.writeFile,fs,'message.txt','word')
.then(() => wrapper(fs.appendFile,fs,'message.txt','word'))
.then(() => wrapper(fs.readFile,fs,'message.txt','word'))
.then(data => console.log(data))
.catch(err => console.log(err));
/*第二题*/
var http = require('http');
var url = require('url');
function delayPromise(ms) {
return new Promise((resolve,reject) => {
setTimeout(reject, ms);
});
}
function get(url,ms) {
return new Promise.race([
delayPromise(ms),
wrapper(request,null,url).then(data => {
return JSON.parse(data);
})
]);
}
get('http://demos.so/result/homework.promise.userInfo')
.then( data => {
Promise.all([get('http://demos.so/result/userid=' + args['_id']), get('http://demos.so/result/student=' + args['_id'])])
}
.then( data => console.log(data))
.catch( err => console.log(args));
/*
*作业一:
*/
var fs = require('fs');
Promise.resolve().then(function(){
return new Promise(function(resolve,reject){
fs.writeFile('test.txt', 'Qi Junxin gets to learn Promise!', function(err){
err ? reject(err) : resolve();
});
})
}).then(function(){
return new Promise(function(resolve,reject){
fs.appendFile('test.txt', 'This is the second part.', function(err){
err ? reject(err) : resolve();
});
})
}).then(function(){
return new Promise(function(resolve,reject){
fs.readFile('test.txt','utf8',function(err,data){
err ? reject(err) : console.log(data);
})
})
}).catch(function(err){
console.log(err);
});
/*
*作业二:
*/
var request = require('request'),
userInfo = 'http://demos.so/result/homework.promise.userInfo',
publicUrl = 'http://demos.so/result/userid=',
studyUrl = 'http://demos.so/result/student=';
var delay = 1000; //ms
var timeoutCtrl = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
reject('Timeout'+delay+'ms')},
delay);
})
};
var getWithPromise = function(url){
var task = new Promise(function(resolve,reject){
request.get({url: url, json: true}, function (error, response, body) {
if(error) reject(err);
if(response.statusCode != 200) reject(response.statusCode);
resolve(body);
});
});
return Promise.race([task,timeoutCtrl()]);
};
var getPost = function(user){
return Promise.all([getWithPromise(publicUrl+user['_id']),getWithPromise(studyUrl+user['_id'])]);
};
getWithPromise(userInfo).then(getPost).then(function (data) {
console.log(data);
}).catch(function (err) {
console.log(err);
});
var fs = require('fs');
function writeFile(filename, data) {
return new Promise (function(resolve, reject) {
fs.writeFile(filename, data, function(err){
if(err)
reject(err);
else
resolve();
});
// setTimeout(function () {
// resolve(11);
// }, 2000)
});
}
function appendFile(filename, data) {
return new Promise (function(resolve, reject) {
fs.appendFile(filename, data, function(err){
if(err)
reject(err);
else
resolve();
});
});
}
function readFile(filename) {
return new Promise (function(resolve, reject) {
fs.readFile(filename, 'utf8', function(err, data){
if(err)
reject(err);
else
console.log(data);
});
});
}
Promise.resolve().then(function(){
return writeFile('./test.txt', 'Hello');
}).then(function(){
console.log(22);
return appendFile('./test.txt', 'World');
}).then(function(){
console.log(33)
return readFile('./test.txt');
}).catch(function(err){
console.log(err);
});
----------------------------------------------------------------------------------
var request = require('request');
var url = "http://demos.so/result/homework.promise.userInfo",
useUrl = "http://demos.so/result/userid=",
studyUrl = "http://demos.so/result/student=";
function requestPromise(url) {
return new Promise(function (resolve, reject) {
request(url, function (error, response, data) {
if (!error && response.statusCode == 200) {
var jsonData = JSON.parse(data);
resolve(jsonData);
//console.log(jsonData);
}
});
});
}
function getUse(data) {
return requestPromise(useUrl + data._id);
}
function getStudy(data) {
return requestPromise(studyUrl + data._id);
}
requestPromise(url).then(function(data) {
return Promise.all([getUse(data), getStudy(data)]);
}).then(function(data) {
console.log(data[0], data[1]);
});
/**
作业1:
**/
var fs = require('fs');
opFile = {
fileName : 'a.txt',
str1 : 'this is my wirte - string!',
str2 : 'append to this !',
main : function(){
this.writeFile(this.fileName,this.str1).then(
this.appendFile(this.fileName,this.str2)
).then(
this.readFile(this.fileName)
).catch(function (err){
console.log(err)
})
},
//写文件
writeFile : function (filename,string){
return new Promise(function (resolve, reject){
fs.writeFile(filename, string, 'utf8',function (err){
if (err){
reject(err)
}else {
resolve();
}
})
});
},
//文件内容追加
appendFile : function (filename,string) {
return new Promise(function (resolve, reject){
fs.appendFile(filename, string, 'utf8',function (err){
if (err){
reject(err)
}else {
resolve()
}
})
})
},
//文件读取
readFile : function (filename){
fs.readFile(filename, 'utf8', function (err, res){
if (err){
console.log(err)
}else {
console.log('读文件'+filename+'结果为:', res);
}
});
}
}
opFile.main();
/**********************/
/**
作业2:
**/
var request = require('request');
getInfo = {
// 获取用户ID等信息
getId : function() {
return new Promise(function (resolve, reject){
request('http://demos.so/result/homework.promise.userInfo', function (error, response, data) {
if (!error && response.statusCode == 200){
resolve(data)
}else{
reject(err)
}
});
});
},
//用户发布过的帖子
getPub : function(id){
return new Promise(function (resolve, reject){
request('http://demos.so/result/userid='+id, function (error, response, data) {
if (!error && response.statusCode == 200){
resolve(data)
}else{
reject(err)
}
});
});
},
//用户学习过的帖子
getStu : function(id){
return new Promise(function (resolve, reject){
request('http://demos.so/result/student='+id, function (error, response, data) {
if (!error && response.statusCode == 200){
resolve(data)
}else{
reject(err)
}
});
});
},
//并发请求
all : function(id){
var self = this;
Promise.all([self.getPub(id),self.getStu(id)]).then(function (results){
console.log(results);
}).catch(function(error){
console.log('catch',error);
});
},
main : function(){
var self = this;
self.getId().then(function(data){
//这里返回的data为字符串类型
var userinfo = JSON.parse(data);
var id = userinfo._id;
self.all(id);
})
}
}
getInfo.main();
刘博文,柏盼 2016年7月15日
Promise原理与使用
提前预习资料
https://www.promisejs.org/ http://liubin.org/promises-book/
教学大纲
演讲目标
通过教学,让大家掌握Promise的整体原理,最佳实践,以及在项目中熟练使用
作业
使用Node和Promise的Api,实现以下需求。
资料推荐
promise反模式