如何理解Promise.resolve(it.throw(err))。那么(handleResult)?

时间:2016-04-25 17:15:41

标签: promise ecmascript-6

我正在阅读标题为“你不了解JS:ES6& amp;”的第4章。除了” 我知道Promise.resolve(..)在将可执行或立即值传递给此静态函数时会发生什么。 但如果它转到那个Promise.resolve(it.throw(err))呢?

整个代码说明了承诺+生成器模式,如:

function run(gen) {
    var args = [].slice.call( arguments, 1), it;

    it = gen.apply( this, args );

    return Promise.resolve()
        .then( function handleNext(value){
            var next = it.next( value );

            return (function handleResult(next){
                if (next.done) {
                    return next.value;
                }
                else {
                    return Promise.resolve( next.value )
                        .then(
                            handleNext,
                            function handleErr(err) {
                                return Promise.resolve(
                                    it.throw( err )
                                )
                                .then( handleResult );
                            }
                        );
                }
            })( next );
        } );
}

我的主要问题是拒绝处理程序 - function handleErr(err){..} 如果承诺链不断发展,它将如何运作以及将会发生什么。

1 个答案:

答案 0 :(得分:2)

  

但如果它转到那个Promise.resolve(it.throw(err))呢?

it.throw(..)的结果是IteratorResult对象:{ value: .., done: true },与it.next(..)的结果相同。我将该对象包装在Promise.resolve(..)的承诺中,以便在下一个刻度执行{{1>}时将对象值传回handleResult(..)

@Bergi评论中建议的不仅仅是.then(handleResult)的原因是因为这会在此刻度上执行return handleResult(it.throw(err)),这不是我们想要的(用于调用堆栈目的) )。

  

handleResult(..)它是如何运作的,如果承诺链继续发展将会发生什么。

仅当function handleErr(err){..}(通过handleErr(..)取消)是最终被拒绝的承诺时,才会调用{p> next.value。例如:

Promise.resolve(next.value)

此处,被拒绝的承诺位于run(function*(){ yield Promise.reject(42); }); 来自第一个next.value来电,it.next(..)只是将其作为被拒绝的承诺,Promise.resolve(next.value)导致{使用被拒绝的then(handleNext,handleErr)值调用{1}}。

现在,handleErr(..)尝试将此异常值(42)返回到生成器中,以防生成器中的某些等待it.throw(err)捕获它。

例如,如果我们的生成器确实有42,就像这样:

try..catch

...然后会捕获try..catch异常,然后run(function*(){ try { yield Promise.reject(42); } catch (err) { return 10; } }); 会发生。因此,42调用将正常返回return 10

现在,it.throw(..)会将其提升为正常履行的承诺,并在下一个标记处调用{ value: 10, done: true },并将该对象作为其Promise.resolve(..)参数。 handleResult(..)传递,next返回if (next.done),返回通过递归的promise链,直到最终解析最初的return next.value调用返回。

但是,由于我们的原始生成器10,当run(..)发生时,它抛出的异常会立即退出,异常中止当前{ {1}}致电。由于try..catchit.throw(next.value)启动,handleErr(..)将该异常提升为被拒绝的承诺,该承诺通过递归承诺链返回,最终拒绝原始调用{{{}的最外层承诺。 1}}返回。