Justin's Words

ECMAScript6 Promise

Promise 解释

The Promise object is used for deferred and asynchronous computations.

Promise 语法

1
2
new Promise(executor);
new Promise(function(resolve, reject) { ... });

Promise 结构

Constructor
1
new Promise(function(resolve, reject) {});

resolve(thenable)

Your promise will be fulfilled/rejected with the outcome of thenable

resolve(obj)

Your promise is fulfilled with obj

reject(obj)

Your promise is rejected with obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error. Any errors thrown in the constructor callback will be implicitly passed to reject(). Instance Methods

promise.then(onFulfilled, onRejected)

onFulfilled is called when/if “promise” resolves. onRejected is called when/if “promise” rejects. Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. Both callbacks have a single parameter, the fulfillment value or rejection reason. “then” returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve. If an error is thrown in the callback, the returned promise rejects with that error.

promise.catch(onRejected)

Sugar for promise.then(undefined, onRejected)

简单例子
1
2
3
4
5
6
7
8
9
10
11
12
13
var p = new Promise(function(resolve, reject) {
if (false) {
resolve('Stuff worked!');
} else {
reject('It broke');
}
});

p.then(function(result) {
console.log(result);
}, function(err) {
console.log(err);
});
接受参数的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function get(url) {
return new Promise(function(resolve, reject) {
fs.readFile(url, 'utf8', function(err, data) {
if (err) reject(err);
resolve(data);
});
});
}

get('es.js').then(function(response) {
console.log(response);
}, function(error) {
console.error(error);
});
还可以用 Promise.catch() 捕获错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function get(url) {
return new Promise(function(resolve, reject) {
fs.readFile(url, 'utf8', function(err, data) {
if (err) reject(err);
resolve(data);
});
});
}

get('es.js').then(function(response) {
console.log(response);
}, function(error) {
console.error(error);
});
链式请求
1
2
3
4
5
get('es.js').then(function(response) {
console.log(response);
}).then(undefined, function(err) {
console.error(err);
});
异步请求例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function get(url) {
// Return a new promise.
return new Promise(function(resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);

req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// Resolve the promise with the response text
resolve(req.response);
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};

// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};

// Make the request
req.send();
});
}

get('story.json').then(function(response) {
console.log("Success!", response);
}, function(error) {
console.error("Failed!", error);
});

Q

_Q_ 指的是 kriskowal/q,一个提供 Promise 特性的组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var fs = require('fs');
var Q = require('q');

function get(url) {
var d = Q.defer();
fs.readFile(url, 'utf8', function(err, data) {
if (err) d.reject(err);
d.resolve(data);
});
return d.promise;
}

get('es6.js').then(function(data) {
return data.length;
}).then(function(data) {
console.log(data);
}).fail(function(err) {
console.log(err);
});