JS Asynchronous Series--promise notes

Source: Internet
Author: User

Promise

The motives for studying Promise are broadly as follows:

    • Unfamiliar with its API and curiosity about the implementation mechanism;

    • Many libraries (such as fetch) are based on the Promise package, so to understand the preconditions of these libraries first familiar with Promise;

    • To understand other more advanced asynchronous operations to be familiar with the Promise first;

Based on these objectives, a repromise conforming to the promise/a+ specification is practiced.

This series of notes is a total of three articles, as a previous article on the split and correction of the node. JS Asynchronous Xor Shang.

    • Promise Notes
    • Generator notes
    • Async Notes
promise/a+ Core

Before implementing a Promise that conforms to the promise/a+ specification, first understand the promise/a+ core and want to understand the promise/a+ specification in a more comprehensive way

    • The Promise operation will only be in one of 3 states: the Incomplete State (pending), the completion state (resolved), and the failure state (rejected);
    • The state of the Promise will only be transformed from the incomplete states to the completed State or to the failed state;
    • Once the state of the Promise is transformed, it cannot be changed;
Repromise API Food Manual Promise.resolve ()

Promise.resolve () There are 4 cases in parentheses

/* 跟 Promise 对象 */Promise.resolve(Promise.resolve(1))// Promise?{state: "resolved", data: 1, callbackQueue: Array(0)}/* 跟 thenable 对象 */var thenable = {  then: function(resolve, reject) {    resolve(1)  }}Promise.resolve(thenable)// Promise?{state: "resolved", data: 1, callbackQueue: Array(0)}/* 普通参数 */Promise.resolve(1)// Promise?{state: "resolved", data: 1, callbackQueue: Array(0)}/* 不跟参数 */Promise.resolve()// Promise?{state: "resolved", data: undefined, callbackQueue: Array(0)}
Promise.reject ()

Promise.reject () returns the parameter value unchanged than Promise.resolve ()

Promise.all (arr)

For Promise.all (arr), all the elements in the parameter array become the decision state before the new Promise is returned.

// 以下 demo,请求两个 url,当两个异步请求返还结果后,再请求第三个 urlconst p1 = request(`http://some.url.1`)const p2 = request(`http://some.url.2`)Promise.all([p1, p2])  .then((datas) => { // 此处 datas 为调用 p1, p2 后的结果的数组    return request(`http://some.url.3?a=${datas[0]}&b=${datas[1]}`)  })  .then((data) => {    console.log(msg)  })
Promise.race (arr)

For Promise.race (arr), a new Promise is returned as long as an element of the parameter array becomes the decision state.

// race 译为竞争,同样是请求两个 url,当且仅当一个请求返还结果后,就请求第三个 urlconst p1 = request(`http://some.url.1`)const p2 = request(`http://some.url.2`)Promise.race([p1, p2])  .then((data) => { // 此处 data 取调用 p1, p2 后优先返回的结果    return request(`http://some.url.3?value=${data}`)  })  .then((data) => {    console.log(data)  })
Promise.wrap (FN)--callback function turn Promise

In the following case, we provide the idea of Promise the callback function.

function foo(a, b, cb) {  ajax(    `http://some.url?a=${a}&b=${b}`,    cb  )}foo(1, 2, function(err, data) {  if (err) {    console.log(err)  } else {    console.log(data)  }})

As above is a traditional callback function use case, as long as the use of Promise.wrap () wrapped Foo function to complete the Promise, use the following:

const promiseFoo = Promise.wrap(foo)promiseFoo(1, 2)  .then((data) => {    console.log(data)  })  .catch((err) => {    console.log(err)  })

The implementation logic of the Promise.wrap is also listed in passing:

Promise.wrap = function(fn) {  return funtion() {    const args = [].slice.call(arguments)    return new Promise((resolve, reject) => {      fn.apply(null, args.concat((err, data) => {        if (err) {          reject(err)        } else {          resolve(data)        }      }))    })  }}
Then/catch/done

These APIs are relatively simple, combined together with

Promise.resolve(1)  .then((data) => {console.log(data)}, (err) => {console.log(err)}) // 链式调用,可以传一个参数(推荐),也可以传两个参数  .catch((err) => {console.log(err)}) // 捕获链式调用中抛出的错误 || 捕获变为失败态的值  .done()                             // 能捕获前面链式调用的错误(包括 catch 中),可以传两个参数也可不传
Practice Process Summary Pit point 1: Event loop

Event Loop: After the synchronization queue finishes executing, the contents of the asynchronous queue are executed after the specified time.

The reason for the single-column event loop is that the order of execution of the code is closely related, where the setTimeout is used to simulate the event loop;

In the code snippet below, the code (③) in SetTimeout () is not executed immediately after execution of the ①, but the number of then calls at that time will be re-entered into the ② and then into ③

excuteAsyncCallback(callback, value) {  const that = this  setTimeout(function() {    const res = callback(value) // ③    that.excuteCallback('fulfilled', res)  }, 4)}then(onResolved, onRejected) {  const promise = new this.constructor()  if (this.state !== 'PENDING') {    const callback = this.state === 'fulfilled' ? onResolved : onRejected    this.excuteAsyncCallback.call(promise, callback, this.data)              // ①  } else {    this.callbackArr.push(new CallbackItem(promise, onResolved, onRejected)) // ②  }  return promise}
Pointing problem of Pit point 2:this

The This in This.callbackArr.push () points to the ' previous ' promise, so in class Callbackitem, This.promise stores the ' Next ' promise (then object).

class Promise {  ...  then(onResolved, onRejected) {    const promise = new this.constructor()    if (this.state !== 'PENDING') {        // 第一次进入 then,状态是 RESOLVED 或者是 REJECTED      const callback = this.state === 'fulfilled' ? onResolved : onRejected      this.excuteAsyncCallback.call(promise, callback, this.data)  // 绑定 this 到 promise    } else {                               // 从第二次开始以后,进入 then,状态是 PENDING      this.callbackArr.push(new CallbackItem(promise, onResolved, onRejected)) // 这里的 this 也是指向‘上一个’ promise    }    return promise  }  ...}class CallbackItem {  constructor(promise, onResolve, onReject) {    this.promise = promise // 相应地,这里存储的 promise 是来自下一个 then 的    this.onResolve = typeof(onResolve) === 'function' ? onResolve : (resolve) => {}    this.onReject = typeof(onRejected) === 'function' ? onRejected : (rejected) => {}  }  ...}
More

More process of practice can refer to test cases. Have a good opinion to welcome the exchange.

JS Asynchronous Series--promise notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.