Promise是异步编程的一种解决方案, ES6 这一特性很大程度上提高了开发者的效率,如果用过Angular的同学,一定会用到$q的resolve和reject函数,同理promise也提供原生的解决方案,不需要任何框架支持。
我们下面看一下代码:
function msgAfterTimeout (msg, who, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout)
})
}
msgAfterTimeout("", "Foo", 100).then((msg) =>
msgAfterTimeout(msg, "Bar", 200)
).then((msg) => {
console.log(`done after 300ms:${msg}`)
})
上面代码如果用ES5实现该如何改写呢?
function msgAfterTimeout (msg, who, timeout, onDone) {
setTimeout(function () {
onDone(msg + " Hello " + who + "!");
}, timeout);
}
msgAfterTimeout("", "Foo", 100, function (msg) {
msgAfterTimeout(msg, "Bar", 200, function (msg) {
console.log("done after 300ms:" + msg);
});
});
对于处理多个异步,类似于$q.all()的语法在ES6中也是支持的, 例如:
function fetchAsync (url, timeout, onData, onError) {
…
}
let fetchPromised = (url, timeout) => {
return new Promise((resolve, reject) => {
fetchAsync(url, timeout, resolve, reject)
})
}
Promise.all([
fetchPromised("http://backend/foo.txt", 500),
fetchPromised("http://backend/bar.txt", 500),
fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
let [ foo, bar, baz ] = data
console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
console.log(`error: ${err}`)
})
对于ES5标准的改写上面代码,是这样的:
function fetchAsync (url, timeout, onData, onError) {
…
}
function fetchAll (request, onData, onError) {
var result = [], results = 0;
for (var i = 0; i < request.length; i++) {
result[i] = null;
(function (i) {
fetchAsync(request[i].url, request[i].timeout, function (data) {
result[i] = data;
if (++results === request.length)
onData(result);
}, onError);
})(i);
}
}
fetchAll([
{ url: "http://backend/foo.txt", timeout: 500 },
{ url: "http://backend/bar.txt", timeout: 500 },
{ url: "http://backend/baz.txt", timeout: 500 }
], function (data) {
var foo = data[0], bar = data[1], baz = data[2];
console.log("success: foo=" + foo + " bar=" + bar + " baz=" + baz);
}, function (err) {
console.log("error: " + err);
});
是不是很简洁很多呢,尝试一下吧!