从这里分析: 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();
}

异步

这个才是关键.

  1. promises //这个是新的写法
  2. generators
  3. async/wait
  4. process.nextTick 这个会出问题
  5. setInterval //这个和timeout没有本质区别.
  6. setTimeout //这个用的比较多
  7. requestAnimationFrame
  8. XMLHttpRequest
  9. WebSocket
  10. Worker
  11. Some HTML5 APIs such as the File API, Web Database API
  12. Technologies that support onload
  13. … 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都可以不用, 如果用简洁的字面量声明的化