Skip to content
New issue

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

ES6 promise & async #11

Open
aototo opened this issue Sep 8, 2017 · 0 comments
Open

ES6 promise & async #11

aototo opened this issue Sep 8, 2017 · 0 comments

Comments

@aototo
Copy link
Owner

aototo commented Sep 8, 2017

Promise

Promise对象有以下两个特点。

  1. 对象的状态不受外界影响, Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

resolve(value) VS resolve(promise)

then(onFulfiled, onRejected)

var d = new Date()
const promiseA = new Promise((resolve, reject) => {
    setTimeout( () => {
      resolve("ok")
    },2000)
})

const promiseB = new Promise((resolve, reject) => {
    resolve(promiseA)
})

promiseB.then( (resolve)=> {
  console.log(resolve, (new Date()) - d)
})

promise2中调用了resolve(promise1),此时promise1的状态会传递给promise2,或者说promise1的状态决定了promise2的状态。所以当promise1进入fulfilled状态,promise2的状态也变为fulfilled,同时将promise1自己的不可变值作为promise2的不可变值.

Promise新建后就会立即执行。


promise 捕获错误

回调函数有同步和异步之分,区别在于对方执行回调函数的时机,异常一般出现在请求、数据库连接等操作中,这些操作大多是异步的。

异步回调中,回调函数的执行栈与原函数分离开,导致外部无法抓住异常。

function fetch(callback) {
    setTimeout(() => {
        throw Error('请求失败')
    })
}

try {
    fetch(() => {
        console.log('请求处理') // 永远不会执行
    })
} catch (error) {
    console.log('触发异常', error) // 永远不会执行
}
//
// Uncaught Error: 请求失败

但是,永远不要在 macrotask 队列中抛出异常,因为 macrotask 队列脱离了运行上下文环境,异常无法被当前作用域捕获 如下。

function fetch(callback) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
             throw Error('用户不存在')
        })
    })
}

如果第三方函数在 macrotask 回调中以 throw Error 的方式抛出异常怎么办?

值得欣慰的是,由于不在同一个调用栈,虽然这个异常无法被捕获,但也不会影响当前调用栈的执行。

macrotask 抛出异常的话,请改为 reject 的方式。

function thirdFunction() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('收敛一些')
        })
    })
}

Promise.resolve

现有对象转为Promise对象

var p = Promise.resolve('foo');
p.then( (resolve) => {
  console.log(resolve);
})

需要注意的是,立即resolve的Promise对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');
// one
// two
// three

下面函数f是同步的,但是用 Promise 包装了以后,就变成异步执行了。

const f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');

async

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。

async function f() {
  return await 123;
}

f().then(v => console.log(v))

具体: http://es6.ruanyifeng.com/#docs/async
参考:
http://imweb.io/topic/57a0760393d9938132cc8da9
http://www.jianshu.com/p/78dfb38ac3d7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant