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

这些Promise题目,让你受益匪浅 #7

Open
hankzhuo opened this issue Mar 29, 2018 · 0 comments
Open

这些Promise题目,让你受益匪浅 #7

hankzhuo opened this issue Mar 29, 2018 · 0 comments

Comments

@hankzhuo
Copy link
Owner

引言

promise我看了好机会,但做题时候都会出错,后来我知道学一个知识点,光看不动手敲代码是不够的。下面几道题做完,真的受益匪浅,题目大部分来自网上,文章后面会提到。

首先,promise 基础知识可以看 mdn。

promise-mdn

题目

第一题

const request = (url) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onload = () => resolve(xhr.responseText);
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send();
  })
}

request(url1)
  .then(data1 => request(data1.url))
  .then(data2 => request(data2.url))
  .catch(err => { 
     throw new Error(err)
  })

request 是个promise对象,有三个状态 pedding、fulfilled、rejected。初始状态为 pendding,调用 resolve时,状态变为 fulfilled,调用rejected时,状态变为 rejected

第二题

const promise  = new Promise((resolve, reject) => {
  // resolve('fulfilled');
  reject('111');
})

promise.then(result => {
  console.log('success...', result)
}, err => {
  console.log("err...", err);
})

promise.then(onFulfilled, onRejected) then接受两个参数,onFulfilled 成功时调用,onRejected 失败时候调用。 一次只会调用其中一个函数。

第三题

const p1 = new Promise((resolve, reject) => {
    resolve(1);
});

const p2 = new Promise((resolve, reject) => {
    resolve(2);
});

const p3 = new Promise((resolve, reject) => {
    resolve(3);
});

Promise.all([p1, p2, p3])
  .then(data => console.log(data))  // [1, 2, 3]
  .catch(err => console.log('err...',err))

Promise.race([p1, p2, p3])
  .then(data => console.log(data)) // 1
  .catch(err => console.log("err...", err));
  • Promise.all()等待所有完成后才调用 then
  • Promise.race() 谁先处理完就直接调用后面函数
  • Promise.resolve() 返回一个 fulfilled 状态的promise对象
  • Promise.reject() 返回一个 rejected 状态的promise对象

第四题

const promise = new Promise((resolve, reject) => {
  console.log(1);
  resolve('resolve');
  console.log(2);
});

console.log(promise);

promise.then(() => {
  console.log(3)
});

console.log(4); 

// 1 2 Promise { 'resolve' } 4 3
  • Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的
  • 注意:上面 promise 内,resolve() 是同步代码,所以立刻被执行了

第五题

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  }, 1000)
})
const promise2 = promise1.then(() => {
  throw new Error('error!!!')
})

console.log('promise1', promise1)
console.log('promise2', promise2)

setTimeout(() => {
  console.log('promise1', promise1)
  console.log('promise2', promise2)
}, 2000)

// promise1 Promise { <pending> }
// promise2 Promise { <pending> }
// promise1 Promise { 'success' }
// promise2 Promise {
//  <rejected> Error: error!!!

promise 有 3 种状态:pending、fulfilledrejected。状态改变只能是 pending->fulfilled 或者 pending->rejected,状态一旦改变则不能再变。上面 promise2 并不是 promise1,而是返回的一个新的 Promise 实例

第六题

Promise.resolve()
  .then(() => {
    return new Error("error!!!");
  })
  .then(res => {
    console.log("then: ", res);
  })
  .catch(err => {
    console.log("catch: ", err);
  });
  
//输出 then: Error: error!!!
  • .then 或者 .catchreturn 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获
  • 因为返回任意一个非 promise 的值都会被包裹成 promise 对象,即 return new Error('error!!!') 等价于 return Promise.resovle(new Error('error!!!'))

6.1

Promise.resolve()
  .then(() => {
    throw new Error("error!!!");
    // return Promise.reject(new Error("error!!!"));
  }, err => {
    console.log('then1: ', err)
  })
  .then(res => {
    console.log("then2: ", res);
  })
  .catch(err => {
    console.log("catch: ", err);
  });
  
//输出 catch:  Error: error!!!

第一个 then 抛出错误,需要后面的捕获错误。

6.2

Promise.reject(1)
  .then(() => {
    return new Error('error!!!')
  })
  .then((res) => {
    console.log('then: ', res)
  })
  .catch((err) => {
    console.log('catch: ', err)
  });
  
  // 输出 catch 1  

前面两个then并没有捕捉错误,所以错误抛到了最后面的catch,中间 then 并不执行了。

6.3

Promise.reject(1)
  .then(() => {
    return new Error("error!!!");
  })
  .then(res => {
    console.log("then: ", res);
  }, err => {
    console.log("haha", err);
  })
  .catch(err => {
    console.log("catch: ", err);
  });
  
//输出 haha 1

错误被第二个 then 捕捉了,最后的 catch 也就不执行了。

第七题

var p = new Promise(function(resolve, reject){
  resolve(1);
});
p.then(function(value){               //第一个then
  console.log(value);
  return value*2;
}).then(function(value){              //第二个then
  console.log(value);
}).then(function(value){              //第三个then
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){              //第四个then
  console.log(value);
  return Promise.reject('reject');
}).then(function(value){              //第五个then
  console.log('resolve: '+ value);
}, function(err){
  console.log('reject: ' + err);
})

// 1 
// 2
// undefined ,因为上一个 then() 没有返回值
// resolve 
// reject: reject

第八题

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log);
  
// 1

.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。

第九题

const promise = Promise.resolve().then(() => {
  return promise;
});
promise.catch(console.error);

// TypeError: Chaining cycle detected for promise #<Promise>

.then .catch`` 返回的值不能是 promise``` 本身,否则会造成死循环。

参考

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

No branches or pull requests

1 participant