We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
文章来源:Promise Anti-patterns
loadSomething().then(function(something) { loadAnotherthing().then(function(anthor) { DoSomethingOnThem(something, anthor); }) })
你这样书写的原因是需要对2个promise的结果进行处理,由于then()接收的是上一个promise返回的结果,因此你无法通过链式写法将其连接起来。
promise
then()
To Fix:
q.all([loadSomething(), loadAnotherThing()]) .spread(function(something, another) { DoSomethingOnThem(something, another); })
q.all()方法将会等待loadSomething和loadAnotherThing都被resolve后调用传入spread方法里面的回调。
q.all()
loadSomething
loadAnotherThing
resolve
spread
##The Broken Chain(断掉的promise链)
先看一段代码:
function anAsyncCall() { var promise = doSomethingAsync(); promise.then(function() { somethingComplicated(); }) return promise; }
这种写法的问题是当somethingComplicated方法中抛出错误无法被捕获。Promise应当是链式的,每次调用then()方法后都会返回一个新的promise。普遍的写法是:最后调用catch()方法,这样在前面的一系列的promise操作当中,发生的任何error都会被捕获。
somethingComplicated
Promise
catch()
error
上面的代码中,当你最后返回的是第一个promise,而非这个promise调用then()方法后的结果,那么promise链也随即断掉。
function anAsyncCall() { var promise = doSomethingAsync(); return promise.then(function() { somethingComplicated() }); }
##The Collection Kerfuffle
当你有一个数组,数组里面的每个项目都需要进行异步的处理。因此你可能会通过递归去做某些事情:
function workMyCollection(arr) { var resultArr = []; function _recursive(idx) { if (idx >= resultArr.length) return resultArr; return doSomethingAsync(arr[idx]).then(function(res) { resultArr.push(res); return _recursive(idx + 1); }); } return _recursive(0); }
这段代码第一眼看上去有点难以理解啊。主要是的问题是如果不知道还有map或者reduce方法,那么你也不会知道有多少个项目需要被链接起来,这样就比较蛋疼了。
map
reduce
上面提到的q.all方法接受一个数组,这个数组里面都是promise,然后q.all方法等待所有这些promise全部被resolve后,得到一个数组,由之前的promise被resolve后的值组成。这个时候我们可以通过map方法去改进上面的代码:
q.all
function workMyCollection(arr) { return q.all(arr.map(function(item) { return doSomethingAsync(item); })); }
上面的递归写法是串行处理的,但是通过q.all和map进行改写后变成并行处理,因此更加高效。
如果你确实需要promise串行处理,那么你可以使用reduce方法:
function workMyCollection(arr) { return arr.reduce(function(promise, item) { return promise.then(function(result) { return doSomethingAsyncWithResult(item, result); }, q()); }); }
虽然不是很整洁,但是肯定有条理。
##The Ghost Promise
有个方法有时需要异步进行处理,有时可能不需要。这时也可以创建一个promise,去保证2种不同的处理方式的连贯性。
var promise ; if(asyncCallNeeded) { promise = doSomethingAsync(); } else { promise = Q.resolve(42); } promise.then(function() { doSomethingCool(); });
还有一种更加整洁的写法,就是使用Q()方法去包裹一个普通值或者promise。
Q()
普通值
Q(asyncCallNeeded ? doSomethingAsync() : 42) .then(function(value) { dosomethingGood(); }) .catch(function(err) { handleTheError(); });
##The Overly Keen Error Handler
then()方法接收2个参数,fullfilled handler以及rejected handler:
fullfilled handler
rejected handler
somethingAync.then(function() { return somethingElseAsync(); }, function(err) { handleMyError(err); })
但是这种写法存在一个问题就是如果有错误在somethingElseAsync方法中抛出,那么这个错误是无法被error handler捕获的。
somethingElseAsync
error handler
这个时候需要将error handler单独注册到then()方法中。
somethingAsync .then(function() { return somethingElseAsync() }) .then(null, function(err) { handleMyError(err); });
或者使用catch()方法:
somethingAsync() .then(function() { return somethingElseAsync(); }) .catch(function(err) { handleMyError(err); });
这2种写法都为了保证在promise链式处理过程中出现错误能被捕获。
##The Forgotten Promise
你调用了一个方法并返回了一个promise。然而,你忘记了这个promise并且创建了一个你自己的:
var deferred = Q.defer(); doSomethingAsync().then(function(res) { res = manipulateMeInSomeWay(res); deferred.resolve(res); }, function(err) { deferred.reject(err); }); return deferred.promise(;
这里面存在着很多无用的代码,并且和Promise简洁的思想正好相悖。
return doSomethingAsync().then(function(res) { return manipulateMeInSomeWay(res); });
相关资料:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
文章来源:Promise Anti-patterns
Nested Promise(嵌套的Promise)
你这样书写的原因是需要对2个
promise
的结果进行处理,由于then()
接收的是上一个promise返回的结果,因此你无法通过链式写法将其连接起来。To Fix:
q.all()
方法将会等待loadSomething
和loadAnotherThing
都被resolve
后调用传入spread
方法里面的回调。##The Broken Chain(断掉的promise链)
先看一段代码:
这种写法的问题是当
somethingComplicated
方法中抛出错误无法被捕获。Promise
应当是链式的,每次调用then()
方法后都会返回一个新的promise
。普遍的写法是:最后调用catch()
方法,这样在前面的一系列的promise
操作当中,发生的任何error
都会被捕获。上面的代码中,当你最后返回的是第一个
promise
,而非这个promise
调用then()
方法后的结果,那么promise
链也随即断掉。To Fix:
##The Collection Kerfuffle
当你有一个数组,数组里面的每个项目都需要进行异步的处理。因此你可能会通过递归去做某些事情:
这段代码第一眼看上去有点难以理解啊。主要是的问题是如果不知道还有
map
或者reduce
方法,那么你也不会知道有多少个项目需要被链接起来,这样就比较蛋疼了。To Fix:
上面提到的
q.all
方法接受一个数组,这个数组里面都是promise
,然后q.all
方法等待所有这些promise
全部被resolve
后,得到一个数组,由之前的promise
被resolve
后的值组成。这个时候我们可以通过map
方法去改进上面的代码:上面的递归写法是串行处理的,但是通过
q.all
和map
进行改写后变成并行处理,因此更加高效。如果你确实需要
promise
串行处理,那么你可以使用reduce
方法:虽然不是很整洁,但是肯定有条理。
##The Ghost Promise
有个方法有时需要异步进行处理,有时可能不需要。这时也可以创建一个
promise
,去保证2种不同的处理方式的连贯性。还有一种更加整洁的写法,就是使用
Q()
方法去包裹一个普通值
或者promise
。##The Overly Keen Error Handler
then()
方法接收2个参数,fullfilled handler
以及rejected handler
:但是这种写法存在一个问题就是如果有错误在
somethingElseAsync
方法中抛出,那么这个错误是无法被error handler
捕获的。这个时候需要将
error handler
单独注册到then()
方法中。To Fix:
或者使用
catch()
方法:这2种写法都为了保证在
promise
链式处理过程中出现错误能被捕获。##The Forgotten Promise
你调用了一个方法并返回了一个
promise
。然而,你忘记了这个promise
并且创建了一个你自己的:这里面存在着很多无用的代码,并且和
Promise
简洁的思想正好相悖。To Fix:
相关资料:
The text was updated successfully, but these errors were encountered: