zhouzhongyuan / qa

Questions recods
MIT License
5 stars 1 forks source link

Promise理解 #6

Open zhouzhongyuan opened 7 years ago

zhouzhongyuan commented 7 years ago
zhouzhongyuan commented 7 years ago

学习资料

zhouzhongyuan commented 7 years ago

要点记录

Promises capture the notion of an eventual value into an object

zhouzhongyuan commented 7 years ago

疑问

  1. This is the main reason promises are so interesting. Once the concept of eventuality is captured like this, we can begin to do some very powerful things. We’ll explore this more later on.

这有什么interesting的?我们可以干什么powerful的事情?

2.

Chaining Promises


function doSomething() {
return new Promise(function(resolve) {
var value = 42;
// setTimeout(function () {
resolve(value)
// },0);
});
}

var promise = doSomething();

promise .then(function(value) { console.log('Got a value:', value); }) .then(function(value) { console.log('Got the same value again:', value); });

function Promise(fn) { console.log('new a Promise'); var state = 'pending'; var value; var deferred = null;

function resolve(newValue) {
    console.log('resolve is called')
    value = newValue;
    state = 'resolved';

    if(deferred) {
        handle(deferred);
    }
}

function handle(handler) {
    if(state === 'pending') {
        deferred = handler;
        return;
    }

    if(!handler.onResolved) {
        handler.resolve(value);
        return;
    }
    console.log('handle value');
    var ret = handler.onResolved(value);
    handler.resolve(ret);
}

this.then = function(onResolved) {
    console.log('then is called')
    return new Promise(function(resolve) {
        handle({
            onResolved: onResolved,
            resolve: resolve
        });
    });
};

fn(resolve);

}


在这段代码中,在执行第一个`then`的时候`handle`中的`state`应该是`pending`,但是它为什么是`resolved`?

答: 用到了闭包。[How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work).
    [JavaScript执行步进器](http://pythontutor.com/javascript.html#mode=display)
zhouzhongyuan commented 7 years ago

疑问3

如果then里面的函数返回的是一个Promise怎么办?

例如:

doSomething().then(function (result) {
    // doSomethingElse 返回 a promise
    return doSomethingElse(result);
}).then(function (finalResult) {
    console.log("最终结果是", finalResult);
});

后果:

finalResult不会是正确的最终值,而是一个Promise

简陋的解决方式:

doSomething().then(function (result) {
    // doSomethingElse 返回 a promise
    return doSomethingElse(result);
}).then(function (anotherPromise) {
    anotherPromise.then(function(finalResult) {
    console.log("最终结果是", finalResult);
    });    
});

评价:这种解决方式能达到本来的目的,但是代码很恶心(then里面包含回调)。

好的解决办法

function resolve(newValue) {
    if(newValue && typeof newValue.then === 'function') {
        newValue.then(resolve);
        return;
    }
    state = 'resolved';
    value = newValue;

    if(deferred) {
        handle(deferred);
    }
}

评价:在reslove中判断返回值是否为Promise,如果是,执行newValue.then(resolve);

为什么执行一个newValue.then(resolve)就能解决返回值为Promise的问题呢?

>  `newValue`是一个Promise,
  - 如果`newValue`执行之后是一个**非Promise的返回值**,那么,就可以交个`handle`处理,
  - 如果`newValue`执行之后是一个**Promise的返回值**, 那么,接着执行`newValue.then(resolve)`