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.
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)