Js再起之异步回调和链式调用
从这里分析: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop
js的回调就是基于settimeout.
- 自己写一个回调函数
- 回调函数是最迫切的.
- 链式调用
回调
//这个特别简单, 参数是函数就可以了. 直接调用.
function doSomething(callback) {
// ...
// Call the callback
callback('stuff', 'goes', 'here');
}
function foo(a, b, c) {
// I'm the callback
alert(a + " " + b + " " + c);
}
doSomething(foo);
//callback形式
function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback, salutation) {
// Call our callback, but using our own instance as the context
callback.call(this, salutation);
}
function foo(salutation) {
alert(salutation + " " + this.name);
}
var t = new Thing('Joe');
t.doSomething(foo, 'Hi'); // Alerts "Hi Joe" via `foo`
//apply形式
function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback) {
// Call our callback, but using our own instance as the context
callback.apply(this, ['Hi', 3, 2, 1]);
}
function foo(salutation, three, two, one) {
alert(salutation + " " + this.name + " - " + three + " " + two + " " + one);
}
var t = new Thing('Joe');
t.doSomething(foo); // Alerts "Hi Joe - 3 2 1" via `foo`
//判断一下更健壮.
if (callback && typeof(callback) === "function") {
// execute the callback, passing parameters as necessary
callback();
}
异步
这个才是关键.
- promises //这个是新的写法
- generators
- async/wait
- process.nextTick 这个会出问题
- setInterval //这个和timeout没有本质区别.
- setTimeout //这个用的比较多
- requestAnimationFrame
- XMLHttpRequest
- WebSocket
- Worker
- Some HTML5 APIs such as the File API, Web Database API
- Technologies that support onload
- … many others
setTimeout( yourFn, 0 );
Promise.resolve("World").then(console.log); // then callbacks are always asynchronous
console.log("Hello");
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
链式调用
每个函数返回的都是下一步的调用. 7个写法召唤神龙.
//直接声明的简洁写法.
var test = {
someFunc: function () {
console.log('someFunc')
return test;
},
someOtherFunc: function () {
console.log('someOtherFunc')
return test;
}
}
test.someFunc().someOtherFunc();
//直接声明了另外一个写法, 优点是剥开了最大的括号. 降低了大括号的嵌套
var test = {}
test.someFunc=function () {
console.log('someFunc111')
return test
}
test.someOtherFunc=function () {
console.log('someOtherFunc222')
return test;
}
test.someFunc().someOtherFunc();
//promise写法
//function写法
var test = function(){ //匿名函数表达式, this不很安全.
var self = {}; //用self=this也是可以的, this的作用域会有问题, 所以不建议使用.
console.log('test called')
function someFunc() {
console.log('someFunc')
return self;
}
function someOtherFunc() {
console.log('someOtherFunc')
return self;
}
self.someFunc = someFunc;
self.someOtherFunc = someOtherFunc;
return self;
}
test().someFunc().someOtherFunc();
//prototype+function写法
function test(){ //构造函数, 这种形式this是安全的.
console.log('test called')
}
test.prototype.someFunc=function() {
console.log('someFunc')
return this
}
test.prototype.someOtherFunc=function() {
console.log('someOtherFunc')
return this
}
var xxx = new test(); //因为是这么弄得.
xxx.someFunc().someOtherFunc();
//this版本
function MyNumber(n) {
function x () { }
x.one = function() { n++; return this; };
x.valueOf = function() { return n; };
return x;
}
MyNumber(5).one().one()
> 7
//更this的版本
function MyNumber(n) {
var internal = Number(n);
this.one = function() {
internal += 1;
// here comes the magic that allows chaining:
return this;
}
// this.two analogous
this.valueOf = function() {
return internal;
}//据说写toString也可以.
}
new MyNumber(5).one().two().two().valueOf(); // 10
// 冒号写法也是可以的, 这里用了this, 其实不太好, 不建议用
var myMethods = {
one: function() {
console.log('one');
// You can return 'this' or reference the object by name
return this; //直接返回myMethods更合理, 因为this的作用域.....
// or
// return myMethods;
},
two: function() {
console.log('two');
return this;
}
};
myMethods.one().two().one().two();//=> 'one', 'two', 'one', 'two'
//prototype写法
//字面量声明可以使用下面这样的写法, 不过我就不做试验了. 反正我不会这么写的.
b.__proto__.xxx=function(){}
- promise也可以实现链式调用. 明天仔细搞.
- this看了一下.
this一般是function才能限制住, {}大括号限制不住, 并且很多时候this指的是dom上层元素. 所以: this少用为妙.
而且在匿名函数中使用this都不是很安全.
一般情况下, this和prototype都可以不用, 如果用简洁的字面量声明的化