blogs icon indicating copy to clipboard operation
blogs copied to clipboard

Promiss / async / awiat

Open forever-z-133 opened this issue 7 years ago • 0 comments

本文将梳理描述一些 异步程序开发方面的流派也不见得是异步的,回调很多的程序来开发的话也是这一套

  • 回调函数
  • 事件监听
  • $.Deferred
  • Promiss
  • async / awiat
  • continuation.js
  • Generator

回调函数 callback

function fn1(callback) {
  setTimeout(function(){
    callback && callback();
  }, 100);
}
fn1(function(){ alert(); });

回调函数的优点是 简单、容易理解和部署。

缺点是不利于代码的阅读和维护,各个部分之间 高度耦合流程会很混乱,而且每个任务只能指定一个回调函数。 比如 fn1(fn2(fn3)) 既不好看,改为 fn3(fn2) 也不见得很方便(比如未封装成方法的时候),绑两个回调比较麻烦等问题。

未封装时候写回调,形象可以戏称未“回调金字塔”,尖角向右的那个样子

事件监听

我们就用 jquery 的 on + trigger 也是非常漂亮的。

function fn1() {
  setTimeout(function(){
    $('.my-list').triggle('done')
  }, 100);
}
$('.my-list').on('done', f2).on('done', f3);

事件驱动模式,任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以去耦合,有利于实现模块化

缺点是整个程序都要变成事件驱动型,运行流程会变得很 不清晰

其实你把它叫做“观察者模式”或者“订阅发布模式”也是可以的,只是把 $('x') 改成了别的。 比如 var Event = new Vue(); Event.$on('xx'); Event.$emit('xx') 这种事件调度器。 原生如何写观察者模式呢,可见 这里

$.Deferred

当时初次接触到 $.Deferred 时惊叹不已,这世间竟还有如此骚的操作。

$.ajax("test.html")
.done(function(){ alert('哈哈,成功了!'); })
.done(function(){ alert('我还能再运行一次'); })
.fail(function(){ alert('出错啦!'); });

// 或者多个 ajax 一起玩耍
$.when($.ajax('test1.html'), $.ajax('test2.html'))
.done(function(){ alert('哈哈,成功了!'); })

基于 $.Deferred 自定义的异步就按下面这样写

var dtd = $.Deferred();
function wait(dtd){
  setTimeout(function() {
    dtd.resolve('finish');
  }, 500);
  return dtd;
};

$.when(wait(dtd))
.done(function(text){ alert(text); })
.done(function(text){ alert(text); })

jQuery 源码:https://github.com/jquery/jquery/blob/master/src/deferred.js

原理大致为,

Promise

function fn1(){
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      alert('');
    }, 500);
  })
}

ES6 标准化了的 Promise 相比 $.Deferred 有什么不一样呢,其实 var Promise = $.post 这样来看还真没什么不同。

兼容代码:https://www.promisejs.org/polyfills/promise-7.0.4.js 虽然不是源码,但可以大致一窥 Promise 的实现原理。

async / awiat

continuation.js

GitHub:https://github.com/BYVoid/continuation

其实还不理解它的原理,但它确实做到了,有兴趣的可以研究一番,在此只作拓展阅读了。

function textProcessing(ret) {
  fs.readFile('somefile.txt', 'utf-8', cont(err, contents));
  if (err) return ret(err);
  contents = contents.toUpperCase();
  fs.readFile('somefile2.txt', 'utf-8', cont(err, contents2));
  if (err) return ret(err);
  contents += contents2;
  fs.writeFile('somefile_concat_uppercase.txt', contents, cont(err));
  if (err) return ret(err);
  ret(null, contents);
}

textProcessing(cont(err, contents));
if (err) console.error(err);

Generator

http://www.ruanyifeng.com/blog/2015/04/generator.html

forever-z-133 avatar Oct 13 '17 04:10 forever-z-133