Asynchronous Solution one: promise

For the promise has been before, that is, with a meal, never get to the bottom of its internal principle, accidentally saw some of the topics on the order of output also promise meal guessing. . . Haha, after my colleagues promise to share (though I do not get up because I listen to), but the sense of learning promise on this next. . . What is not said, is to learn. . .

With questions to learn:

  1. promise is doing?
  2. promise in what ways?
  3. How pomise achieve chained calls? Before jquery can also call chain, the difference between them before?
  4. How then is to determine promise of resolve on the front or reject executing the get the result and then executed?
  5. A handwritten meet promiseA + the promise method (write a little, can not be found by promiseA + test cases, have given up, holding written by someone else looked carefully)

promise is doing

asynchronous programming promise a solution, it can achieve the asynchronous operation according to the flow expressed in synchronous operation. It may receive an asynchronous request, and then subsequent operations in which the results of previous methods can be asynchronous request, chained calls use the result of the asynchronous request expressed in a synchronous manner.

Misunderstanding

1. promise only asynchronous programming solution itself is not an asynchronous request, the new Promise () method inside pass will be executed immediately.

const promise = new Promise(function (resolve, reject) {
  console.log('12')
  setTimeout(function () {
    resolve('success')
  }, 1000)
})
promise.then(function (success) {
  console.log(success)
})
// 执行结果: 先输出12,过了一秒后再输入success
复制代码

resolve within 2. new Promise is performed asynchronously, and then all the methods and catch method will also be executed in the current script execution complete all tasks synchronization

const myPromise = new Promise(function (resolve, reject) {
  console.log('1')
  resolve('2')
  console.log('3')
})
myPromise.then(function (success) {
  console.log(success)
})
setTimeout (function () {
    // 这里可以看到前面myPromise已经resolved了,但是他还是会在最后执行,因为then内部也是异步操作
    myPromise.then(function (success) {
        console.log('again', success)
    })
    console.log('4')
}, 1000)
console.log('5')
// 执行结果是: 1 3 5 2 4 again 2
复制代码

What are some ways promise

Basic Usage

const promise = new Promise(function(resolve, reject) {
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
promise.then(function(value) {}, function (error) {})
复制代码

Basic usage is simple recap:

  1. Three states: - pending (in progress) - fulfilled (has succeeded) -rejected (failed)
  2. Pass into the new Promise resolve method returns a successful result, reject the result is returned failure
  3. The method then instantiates new Promise after receiving two callback functions, and reject, respectively resolve callbacks

Mounted on a prototype method

Promise.prototype.then()&&Promise.prototype.catch()

  • then: function within the process is performed in a state Promise resolve the case, and then the method is an asynchronous operation, if the previous new new Promise not resolve, then passed in the interior do not perform the function
  • catch: a function within the method is performed in a case where the state is reject Promise, and the catch is an asynchronous operation method, then the method and catch are not the same, an error or reject it in front of the new new Promise (), the method will catch inside carried out.

then () and catch () is a Promise default instance of an object returned, even if the other return information, return remains Promise instance of an object, or state and this promise is resolve

Promise.prototype.finally()

Promise objects regardless of how the final state, finally method will be executed, (promise is pedding state will not execute finally method, resolve and reject will be executed)

Promise mount the object's method

Promise.resolve() && Promise.reject()

Convert an existing target object Promise

Promise.all()

The plurality of instances Promise Promise packaged into a new instance.

var p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p1')
  }, 1000)
})
var p2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p2')
  }, 2000)
})
var p3 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p3')
  }, 3000)
})
var p = Promise.all([p1, p2, p3]).then((value) => {
  console.log(value)
}).catch((err) => {
  console.log(err)
})
// 返回值:['p1', 'p2', 'p3']
复制代码

Promise of state here is determined by p1, p2, p3 of:

  1. When p1, p3, P2 and status are resolve, p1, p2 and p3 are passed to the return value in the form of an array of p in a subsequent method then
  2. Wherein when there becomes reject, the reject of a first example of a state of a return value is passed to subsequent catch p's method
  3. If the previous passed in as a parameter is rejected state promise of example, and defines its own catch method, it does not trigger a subsequent Promise.all () method is then
  4. If the previous catch method as a parameter promise instances have come in state rejected, and it has a catch method, then it will not start back Promise.all (), it will trigger then () method.

Promise.race()

Promise to convert an existing object to the object, as long as there is one instance among p1, p2, p3 lead changes state, the state p to change with it. Promise to return the value of that instance of the first to change, it is passed to the callback function p.

How pomise achieve chained calls? Before jquery can also call chain, the difference between them before?

How to achieve the promise chained calls

After each execution of Promise then catch or method, is a new instance of the object returned Promise, then such may be used or another method catch, and can get back on a return value then the method.

E.g:

Internal function then return a value a. We then found that the method executed, returns a new instance of promise, it is a promisevalue

Based on the above bedding, we know that the chain is through internal calls and then catch methods return new Promise ()

How to call jquery achieve chain

By return this, in its prototype method has finished executing itself will teturn

var Jquery = function () {

}
Jquery.prototype = {
  css: function (attr, data) {
    return this
  },
  hide: function () {
    console.log('hide')
    return this
  }
}
var jq = new Jquery()
jq.css().hide()
复制代码

Here jq method called css, css method will first look at the jq, is not found, then went to the prototype constructor Jquery's looking for, find and implement methods css, css prototype in return this method of this points to the jq

Difference between the two

After the promise carried out then or catch methods, each returns a new instance of Promise, jquey has returned all its own

The promise then is how to determine the front or resolve to get the result of executing the re-reject execution

Here to learn a bit written by someone else's promise, through this study to some intermediate code on this part of the

const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
// promise 对象上有resolve,reject,all,race等方法,原型上有then,catch,finally方法
class myPromise {
  constructor (fn) {
    // 首先需要判断fn是否是一个函数
    if (typeof fn != 'function') return 'fn is not function'
    this.PromiseStatus = PENDING
    this.PromiseValue = null
    this.PromiseReason = null
    this.onResolvedCallbacks = []
    this.onRejectedCallbacks = []
    const resolve = value => { // 代码块一
      if(value instanceof Promise) {
        return value.then(resolve, reject);
      }
      // new Promise构造函数传进来的函数fn会立即执行,但是在new Promise内resolve和reject是异步操作(如何做到异步操作 =>使用setTimeout确保new Promise后的then和catch方法会在fn函数执行完才触发)
      setTimeout(() => {
        if (this.PromiseStatus == PENDING) {
          this.PromiseStatus = RESOLVED
          this.PromiseValue = value
          this.onResolvedCallbacks.map(cb => {
            this.PromiseValue = cb(this.PromiseValue)
          })
        }
      })
    }
    const reject = value => {
      setTimeout(() => {
        if (this.PromiseStatus == PENDING) {
          this.PromiseStatus = REJECTED
          this.PromiseReason = value
          this.onRejectedCallbacks.map(cb => {
            this.PromiseReason = cb(this.PromiseReason)
          })
        }
      })
    } 
    try { // 代码块二
      // 立即执行new Promise内的
      fn(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }
  then (onResolved, onRejected) { // 代码块三
    onResolved = typeof onResolved === 'function' ? onResolved : function (v) { return v}
    onResolved = typeof onRejected === 'function' ? onRejected : function (v) { return v}
    console.log('this.PromiseStatus', this.PromiseStatus)
    if (this.PromiseStatus === RESOLVED) { // 代码块三 条件一
      return new myPromise((resolve, reject) => {
        // 什么时候会出现resolve一进来就变成RESOLVED或者REJECTED? 同一个Promise实例被多次调用其then时,这样会走下面的逻辑,为确定then内部还是会异步执行,使用setTimeout
        setTimeout(() => {
          try {
            // 执行then内部的方法
            let x = onResolved(this.PromiseValue)
            resolvePromise(newPromise, x, resolve, reject);
          } catch (err) {
            reject(err)
          }
        })
      })
    }
    if (this.PromiseStatus === REJECTED) { // 代码块三 条件二
      return new myPromise((resolve, reject) => {
        setTimeout(() => {
          try {
            let x = onRejected(this.PromiseReason)
            resolvePromise(newPromise, x, resolve, reject);
          } catch (err) {
            reject(err)
          }
        })
      })
    }
    // 当没有触发resolve或者reject时,将onResolved和onRejected存放在onResolvedCallbacks/onRejectedCallbacks集合中
    if (this.PromiseStatus === PENDING) { // 代码块三 条件三
      return new myPromise ((resolve, reject) => {
        this.onResolvedCallbacks.push(value => {
          try {
            let x = onResolved(value)
            resolvePromise(newPromise, x, resolve, reject);
          } catch (err) {
            reject(err)
          }
        })
        this.onRejectedCallbacks.push(reason => {
          try {
            let x = onRejected(reason)
            resolve(x)
          } catch (err) {
            reject(err)
          }
        })
      })
    }
  }
}
复制代码

Based on the above code, we conducted a simple analysis:

new myPromise(function (resolve, reject) {
    console.log(1)
    resolve(2)
}).then(function (success) {
    console.log(success)
})
复制代码

The above code, the first constructor initializes some values

this.PromiseStatus = PENDING // 初始promise的状态
this.PromiseValue = null // 初始promise resolve状态时的value值
this.PromiseReason = null // 初始promise reject状态时的value值
this.onResolvedCallbacks = [] // 存储resolved状态对应的onResolvedCallbacks事件数组
this.onRejectedCallbacks = [] // 存储rejected状态对应的onRejectedCallbacks事件数组
复制代码

For example, the above simple example: it undergoes steps are:

  1. First into the constructor myPromise into two code blocks, performs the function fn myPromise immediately passed in, where PromiseStatus = PENDING

    try { // 代码块二
        // 立即执行new Promise内的
        fn(resolve, reject)
    } catch (err) {
        reject(err)
    }
    复制代码
  2. When executed fn, further implementation of the resolve function into a block of code, where first pass parameters to resolve the type of judgment was coming, and then we can see setTimeout code here setTimeout internal events in the last eventLoop. Here PromiseStatus = PENDING

    setTimeout(() => {
        if (this.PromiseStatus == PENDING) {
          this.PromiseStatus = RESOLVED
          this.PromiseValue = value
          this.onResolvedCallbacks.map(cb => {
            this.PromiseValue = cb(this.PromiseValue)
          })
        }
      })
    复制代码
  3. Then the trigger myPromise method proceeds to block three, a conditional judgment, three code block into three conditions, returns a new myPromise instance, where the code is executed immediately following

    this.onResolvedCallbacks.push(value => {
        try {
            let x = onResolved(value)
            resolvePromise(newPromise, x, resolve, reject);
        } catch (err) {
            reject(err)
        }
    })
    复制代码

    This operation is to push a function in the onResolvedCallbacks

  4. After the completion of the operation, then perform in front of the last event on the eventLoop

    setTimeout(() => {
        if (this.PromiseStatus == PENDING) {
          this.PromiseStatus = RESOLVED
          this.PromiseValue = value
          this.onResolvedCallbacks.map(cb => {
            this.PromiseValue = cb(this.PromiseValue)
          })
        }
    })
    复制代码

    Found here changed the state PromiseStatus and perform functions onResolvedCallbacks array, this function before the code block III

    value => {
        try {
            let x = onResolved(value)
            resolvePromise(newPromise, x, resolve, reject);
        } catch (err) {
            reject(err)
        }
    }
    复制代码

Therefore, the Promise method then resolve is how to determine the front to get the result of executing the reject or re-execution, two cases:

a = new Promise((resolve, reject) => {
    resolve(1)
})
复制代码
  • To a method called only once then: The method then enters herein, Pending state is determined, a direct return new Promise (), as the storage array resolve a push state function f. After all the synchronization operation is completed, the interior of the resolve function performed at the end of eventLoop removed from the array resolve the state of the function f and executed.
  • Then on a method is called multiple times: when the call then the second method, the foregoing status has changed promise resolved or reject, so, then the method enters determined resolved state or reject, to the setTimeout, then the internal function placed at the end of eventLoop.

Reproduced in: https: //juejin.im/post/5cf0d51e5188254569407029

Guess you like

Origin blog.csdn.net/weixin_33971130/article/details/93169425