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? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: