js promise - 解决异步js回调陷阱

2018-10-26 update: Promise已经基于浏览器内核了。写一段示例代码

var p=new Promise(function(resolve,reject){resolve(1)});
p.then(function(val){console.log(val);return '{"a":'+(val+1)+'}';}).then(JSON.parse).then(val=>{console.log(val)})

为解决多层回调的问题,有以下方案

1. promise ( GitHub Source )

#promise node.js example 1
#
#npm install promise --save
var Promise = require('promise');
var fs = require("fs");
var readFile = Promise.denodeify(require('fs').readFile);
function readJSON(filename){
  return readFile(filename, 'utf8').then(function (res){
    return JSON.parse(res)
  })
}

#example in node.js 2
var Promise = require('promise');
var readFile = Promise.denodeify(require('fs').readFile);
// now `readFile` will return a promise rather than
// expecting a callback

function readJSON(filename, callback){
  // If a callback is provided, call it with error as the
  // first argument and result as the second argument,
  // then return `undefined`. If no callback is provided,
  // just return the promise.
  return readFile(filename, 'utf8')
    .then(JSON.parse)
    .nodeify(callback);
}

#example with jquery
<script src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script>
var jQueryPromise = $.ajax('/data.json');
var realPromise = Promise.resolve(jQueryPromise);
//now just use `realPromise` however you like.

*promise library : bluebird    q

2. Generator

#ES6 new feature
function* count(n){
    for (var x = 0; true; x++) {
#yield会暂停count方法,直到下一次调用count
        yield x
    }
}

#for/of 死循环
for (var x of count()) {
    console.log(x)
}

此特性可以帮助我们写出异步调用代码(包括在for/loop/if/try..catch语句内),并且封装promise后可以异步返回结果。 

var login = async(function* (username, password, session) {
  var user = yield getUser(username);
  var hash = yield crypto.hashAsync(password + user.salt);
  if (user.hash !== hash) {
    throw new Error('Incorrect password');
  }
  session.setUser(user);
});


function async(makeGenerator){
  return function () {
    var generator = makeGenerator.apply(this, arguments);

    function handle(result){
      // result => { done: [Boolean], value: [Object] }
      if (result.done) return Promise.resolve(result.value);

      return Promise.resolve(result.value).then(function (res){
        return handle(generator.next(res));
      }, function (err){
        return handle(generator.throw(err));
      });
    }

    try {
      return handle(generator.next());
    } catch (ex) {
      return Promise.reject(ex);
    }
  }
}

async()表明是异步执行,其实是同步执行的,只不过在getUser()和crypt此两处调用前面有yield关键词,将异步调用。最终返回login变量是一个promise。

3. async/await

 

参考

Callback/Promise/Generator/async/await的比较(需要科学上网)

Learn ES2015(ES6)

 

转载于:https://my.oschina.net/swingcoder/blog/856814

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值