LI@NG

JS Promise&Generator

介绍javascript中的promise对象(使用bluebird第三方库) 以及 es6 中新引入的 generator (使用co第三方库) , 使我们代码可以使用同步操作的流程来表达异步操作, 视频观看地址: 点击查看

以下是视频中用到的源文件:

index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.32/bluebird.min.js"></script>
  </head>
  <body>
    <h1>Javascript Promise, Generator教学</h1>
    <ul id="status"></ul>
    <h4>个人信息</h4>
    <pre id="profile-pre"></pre>
    <h4>微博</h4>
    <pre id="posts-pre"></pre>
    <h4>粉丝</h4>
    <pre id="fans-pre"></pre>
    <!-- 四中不同方式去实习异步加载 -->
    <!-- <script src="callbacks.js"></script>-->
    <!-- <script src="clean-callbacks.js"></script> -->
    <!-- <script src="promiseIntro.js"></script> -->
    <!-- <script src="promises.js"></script> -->
    <script src="generators.js"></script>
    <script src="md5.min.js"></script>
    <script src="test.js"></script>
  </body>

</html>

callback.js

var $status = $('#status');
$.ajax({
  type: 'GET',
  url: 'profile.json', // api.weibo.com...
  success: function(profile) {
    $status.append('<li>获取到->个人信息</li>');
    $('#profile-pre').html(JSON.stringify(profile));
    $.ajax({
      type: 'GET',
      url: 'posts.json?id=' + profile.id,
      success: function(posts) {
        $status.append('<li>获取到->微博</li>');
        $('#posts-pre').html(JSON.stringify(posts));
        $.ajax({
          type: 'GET',
          url: 'fans.json?id=' + posts[0].id,
          success: function(fans) {
            $status.append('<li>获取到->粉丝</li>');
            $('#fans-pre').html(JSON.stringify(fans));
          },
          error: function(xhr, status, error) {
            $status.append('<li>error:'+error.toString()+'</li>');
          }
        });
      },
      error: function(xhr, status, error) {
        $status.append('<li>error:'+error.toString()+'</li>');
      }
    });

  },
  error: function(xhr, status, error) {
    $status.append('<li>error:'+error.toString()+'</li>');
  }
});

clean-callback.js

var $status = $('#status');
$.ajax({
  type: 'GET',
  url: 'profile.json',
  success: getposts,
  error: handleError
});

function getposts(profile) {
  $status.append('<li>获取到->个人信息 (第二种方法)</li>');
  $('#profile-pre').html(JSON.stringify(profile));
  $.ajax({
    type: 'GET',
    url: 'posts.json?id=' + profile.id,
    success: getMentionedUser,
    error: handleError
  });
}
function getMentionedUser(posts) {
  $status.append('<li>获取到->微博 (第二种方法)</li>');
  $('#posts-pre').html(JSON.stringify(posts));
  //get fans mentioned in first tweet
  $.ajax({
    type: 'GET',
    url: 'fans.json?id=' + posts[0].id,
    success: function(fans) {
      $status.append('<li>获取到->粉丝 (第二种方法)</li>');
      $('#fans-pre').html(JSON.stringify(fans));
    },
    error: handleError
  });
}
function handleError(xhr, status, error) {
  $status.append('<li>error:'+error.toString()+'</li>');
}

promiseIntro.js

var promise = new Promise(function (resolve, reject) {
  console.log('创建一个promise!');
  //这里面就是异步操作的地方

  $.ajax({
    url:'dsfs',
    success: function (data) {
      resolve(data);
    },
    error: function (err) {
      reject(err);
    }
  })

  // setTimeout(function () {
  //   resolve('Cool, resolved!!!!');
  // }, 1000);
  //
  // setTimeout(function () {
  //   reject('No way!!!! reject!!');
  // }, 3000);

});

promise.then(function (value) {
  console.log('成功!!!!', value);
}, function (err) {
  console.log('Oops 失败!', err);
})

promises.js

var $status = $('#status');
/*
* ES6原生提供了Promise对象
* 所谓Promise对象,就是代表了未来某个将要发生的事件(通常是一个异步操作.
* 它的好处在于,有了Promise对象,就可以将异步操作以同步操作的流程表达出来. chainning 链式....
* 避免了层层嵌套的回调函数

-----------------例子-------------------.

var promise = new Promise(function(resolve, reject) {
  // request...
  if ( 异步操作成功 ){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(value) {
  // failure
});

*/

$.get('profile.json').then(function(profile) {
  $status.append('<li>获取到->个人信息 (Promise方法)</li>');
  $('#profile-pre').html(JSON.stringify(profile));
  return $.get('posts.json?id=' + profile.id);
}).then(function(posts) {
  $status.append('<li>获取到->微博 (Promise方法)</li>');
  $('#posts-pre').html(JSON.stringify(posts));
  return $.get('fans.json?id=' + posts[0].id)
}).then(function(fans) {
  $status.append('<li>获取到->粉丝 (Promise方法)</li>');
  $('#fans-pre').html(JSON.stringify(fans));
}, handleError);


function handleError(xhr, status, error) {
  $status.append('<li>error:'+error.toString()+'</li>');
}

generators.js

var $status = $('#status');

Promise.coroutine(function* () {

  var profile = yield $.get('profile.json');
  $status.append('<li>获取到->个人信息 (Generator方法)</li>');
  $('#profile-pre').html(JSON.stringify(profile));

  var posts = yield $.get('posts.json?id='+profile.id);
  $status.append('<li>获取到->微博 (Generator方法)</li>');
  $('#posts-pre').html(JSON.stringify(posts));

  var fans = yield $.get('fans.json?id='+posts[0].id);
  $status.append('<li>获取到->粉丝 (Generator方法)</li>');
  $('#fans-pre').html(JSON.stringify(fans));

})().catch(function(errs) {
  console.error(errs);
})

fans.json

{
  "id": 1,
  "username": "好朋友"
}

posts.json

[
  {
   "id": 1,
   "title": "javascript this以及函数的call, apply, bind方法",
   "from": "youku"
  },
  {
   "id": 2,
   "title": "Node.js软肋之CPU密集型任务",
   "from": "jsdeveloper.cn"
  },
  {
   "id": 3,
   "title": "全栈开发者/网站应用开发者该学些什么",
   "from": "youku"
  },
  {
   "id": 4,
   "title": "网页响应式布局设计",
   "from": "jsdeveloper.cn"
  }
]

profile.json

{
  "id": 123456,
  "username": "javascript开发者社区",
  "fans": 1254,
  "posts": 277
}