博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Promise/Generator/Co
阅读量:6225 次
发布时间:2019-06-21

本文共 5242 字,大约阅读时间需要 17 分钟。

---恢复内容开始---

 

这三个都是为解决回调而生的, 最近在学习Koa框架, Koa框架主要就是将异步的写法变成的同步, 解决了回调地狱的问题,也易于流程的控制, 于是找了很多篇文章学习, 终于有点感悟了~ >-<

1、Promise

      看名字,Promise(承诺), 很容易联想到, 这个应该是异步操作结果的承诺, 就像数据库操作, 我们要先去find(), find到了之后就去save(), 那我们承诺find到结果后就去save, 这样就实现了异步写法变同步写法 Promise.then(DB.save(){}) 这样,我们就解决了一些些回调函数的问题了

      还是比较正式一些介绍一下Promise:这是一个对象, 用于传递异步操作的信息。

  它的特点

1、Promise对象代表一个异步操作, 有三种状态 Pending(进行中) Resolve(已完成) Reject(已失败) 只有异步操作的结果可以决定当前的状态
2、Promise对象的状态改变: Pending=>Resolved , Pending=>Rejected

  基本用法

var promise = new Promise(function (resolve, reject) {    if (find得了数据成功) {        resolve(数据);    } else {        reject(err)    }})
 
//通过Generator部署Ajax操作function *main() {    var result = yield request('...');    var resp = JSON.parse(result);    console.log(resp.value);}function request(url) {    makeAjaxCall(url, function(response) {        it.next(response);//参数加上response, 作为result的值,否则返回的是undefined    })}var it = next();it.next();
//解决回调地狱step1(function (value1) {   step2(value1, function(value2) {      dothing...        }) })//如果用Promise改写的化Q.fcall(step1)    .then(step2)//step1,2都是异步操作    .then(function(){       dosth...     }, function(err) {       doerr...     })    .done();//用generator控制流程function* longRunningTask() {    try {        var value1 = yield step1();        var value2 = yield step2(value1);    } catch(e) {        s....    }}//这个函数按次序自动执行所有步骤function scheduler(task) {    setTimeout(function() {        var taskObj = task.next(task.value);        if (!taskObj.done) {            task.value = taskObj.value;            scheduler(task)'        }    }, 0);}

 

 

 

/Promise实例生成后, 用then方法分别制定Resolve和Reject的回调函数promise.then(functioin(数据) {    dealWith(数据);    }, function(err) {    handout)(err)    })
//异步加载图片function loadImageAsync(url) {    return new Promise(function(resolve, reject) {        var image = new Image(); //异步加载一张图片        image.onload = function() {            resolve(image);//加载成功把image传给承诺的下个函数作为参数        }        image.onerror = function() {            reject(new Error('Could not load image at + 'url');        }        image.src = url;    })           }
//异步操作的结果是另一个异步操作var p1 = new Promise(function (resolve, reject) {    doSomething();})var p2 = new Promise(function (resolve, reject) {    resolve(p1); //p2需要等待p1的状态进行下一步操作, 等于数据库的save需要等待find的状态,这两个就是两个异步操作})
//Promise.then//上面的可以用这个栗子改写DB.find('someFile').then(    file => save(file.AAA)).then(    AAA => doSomething(AAA),    err   => console.log(err));
//Promise.all用于将多个Promise包装成一个实例var promises = [1, 2, 3, 4, 5, 6, 7].map(function(id) {    return getJSON(id + '.json'); //Promise函数})Promise.all(promises).then(function(posts) {    do(posts);}).catch(function(reason) {}
//Generator和Promise//Generator用于管理流程function getFoo() {    return new Promise(function(resolve, reject) {        resolve('foo');//返回一个Promise对象    })}var g = function *() {    try{        var foo = yield getFoo(); //迭代器到这里才会运行        console.log(foo);    } catch (e) {        console.log(e);    }}// 简单的cofunction run(generator) {    var it = generator(); //生成迭代器实例    function go(result) {        if (result.done) {            return result.value;        }        return result.value.then(function (value) {            return go(it.next(value));        }, function(err) {            return go(it.throw(error));        })'    }    go(it.next()); //启动迭代器遍历}run(g)

 

2、Generator

可以把Generotor看成一个状态机, 封装了内部状态

执行Generator函数返回一个遍历器对象, 调用遍历器对象的next方法可以使得遍历的指针向下走

//生成一个Generator对象function *asd() {    yield 'joe';    yield 'chan';    return 'done';}var asd = asd();asd.next()// { value: 'joe', done: false }asd.next()// { value: 'chan', done: false }asd.next()// { value: 'done', done: true }asd.next()// { value: undefined, done: true } //遇到yield暂停后面的操作, yield后面的表达式的值作为返回对象的value //yield语句没有返回值(总是返回undefined),next(arg)中的arg就被当作上一个yield语句的返回值
//上面最后一点的一个应用function *foo(x) {    var y = 2* (yield x);    var z = yield y;    return z+y}var foo = foo(5);foo,next() //{value:5, done: false}foo.next() //{value:NaN, done: false} //因为yield的返回值是undefinedfoo.next(12) //{value: 24, done: false} //传入参数当作上一次yield的返回值

 异步操作的同步化表达

function *loadUI() {    showLoadingScreen();    yield loaUIAsyncchoromously();//异步操作    hideLoadingScreen(); //异步操作的后续操作(原来的回调函数)}var loader = loadUI();//加载UIloader.next();...//卸载UIloader.next();

 

//通过Generator函数部署Ajax操作function* main() {  var result = yield request("http://...");  var resp = JSON.parse(result);    console.log(resp.value);}//同步方式表达Ajaxfunction request(url) {  makeAjaxCall(url, function(response){    it.next(response);//response作为result的值,   });}var it = main();it.next();//开始遍历迭代器

经典的回调hell

step1(function (value1) {  step2(value1, function(value2) {    dosth...  });});//用Promise改写上面的代码fcall(step1)  .then(step2)  .then(function (value2) {    do...  }, function (error) {    doerr  })  .done(); //Generator函数控制代码运行流程
function* longRunningTask() { try { var value1 = yield step1(); var value2 = yield step2(value1); //do... } catch (e) { doerr } }//同步控制流程
scheduler(longRunningTask()); function scheduler(task) { setTimeout(function() { var taskObj = task.next(task.value); //异步操作 if (!taskObj.done) { task.value = taskObj.value scheduler(task); } }, 0); }
 

参考

http://es6.ruanyifeng.com/#docs/generator

 

转载于:https://www.cnblogs.com/JoeChan/p/4943384.html

你可能感兴趣的文章
设计模式(二)工厂方法(创建型)
查看>>
文本比较算法Ⅵ——用线性空间计算最大公共子序列(翻译贴)
查看>>
Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)
查看>>
KVM 介绍(1):简介及安装
查看>>
Java没有源代码的同步集合~
查看>>
各类总线传输速率【转】
查看>>
KafkaConsumer 长时间地在poll(long )方法中阻塞
查看>>
More than 100 ABAP Interview Faq's(2)
查看>>
Apache Solr查询语法
查看>>
Javascript中typeof instanceof constructor的区别
查看>>
jenkins忘记管理员登陆密码的补救措施
查看>>
[LeetCode] Sliding Window Maximum 滑动窗口最大值
查看>>
Loopup集合类笔记
查看>>
ylbtech-LanguageSamples-Unsafe(不安全代码)
查看>>
Unable to connect to any of the specified MySQL hosts.
查看>>
Android屏幕尺寸适配注意事项
查看>>
JAVA代码中加了Try...Catch的执行顺序
查看>>
三个c#入门小程序
查看>>
docker中使用systemd
查看>>
[模拟电路] 1、模拟调制、解调电路原理
查看>>