[ES6] Ruan Yifeng ES6 learning Promise (1)

1. Meaning

Promise isasynchronous programminga solution for

1. Concept

Simply put, it is a container that holds the results of events (usually an asynchronous operation) that will end in the future. Syntactically, Promisean object from which messages for asynchronous operations can be obtained. PromiseProvide a unified API, all kinds of asynchronous operations can be processed in the same way.

asynchronous programming: fs file operation, database operation, Ajax, timer;

2. Features

  1. The state of the object is not affected by the outside world. The Promise object represents an asynchronous operation with three states

    • pending: in progress
    • fulfilled: has been successful
    • rejected: failed

    Only the result of an asynchronous operation can determine which state it is currently in, and no other operation can change this state.

  2. Once the state changes, it will not change again, and this result can be obtained at any time. State changes have only two states from pendingchanging to fulfilledand from pendingchanging to rejected.

3. Basic usage

ES6 stipulates that Promisean object is a constructor used to generate Promiseinstances.

// Promise构造函数接受一个函数(执行器函数)作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
const promise = new Promise(function(resolve, reject) {
    
    
  // ... some code

  if (/* 异步操作成功 */){
    
    
  // 在异步操作成功时调用,并将异步操作的结果,作为参数value传递出去;
    resolve(value);
  } else {
    
    
  // 在异步操作失败时调用,并将异步操作报出的错误,作为参数error/reason传递出去。
    reject(error);
  }
});

After the Promise instance is generated, you can use the then method to specify the callback functions of the resolved state and the rejected state respectively.

promise.then(function(value) {
    
    
  // success
}, function(error) {
    
    
  // failure
});

thenmethod can accept two callback functions as parameters.

  • The first callback function is called when Promisethe state of the object changesresolved
  • The second callback function is called when Promisethe state of the object changes rejected.

Both functions are optional and do not have to be provided. They all accept Promisethe value passed from the object as a parameter.

// 创建一个新的p对象promise
const p = new Promise((resolve, reject) => {
    
     // 执行器函数
  // 执行异步操作任务
  setTimeout(() => {
    
    
    const time = Date.now() 
    // 如果当前时间是偶数代表成功,否则失败
    if (time % 2 == 0) {
    
    
      // 如果成功,调用resolve(value)
      resolve('成功的数据,time=' + time)
    } else {
    
    
      // 如果失败,调用reject(reason)
      reject('失败的数据,time=' + time)
    }
  }, 1000);
})

p.then(
  value => {
    
     // 接收得到成功的value数据 onResolved
    console.log('成功的回调', value)  // 成功的回调 成功的数据,time=1615015043258
  },
  reason => {
    
     // 接收得到失败的reason数据 onRejected
    console.log('失败的回调', reason)    // 失败的回调 失败的数据,time=1615014995315
  }
)

4. Why use Promise

1. The way to specify the callback function is more flexible

Old: must be specified before starting the async task

// 1. 纯回调的形式
// 成功的回调函数
function successCallback(result) {
    
    
  console.log("声音文件创建成功:" + result);
}
// 失败的回调函数
function failureCallback(error) {
    
    
  console.log("声音文件创建失败:" + error);
}
// 必须先指定回调函数,再执行异步任务
createAudioFileAsync(audioSettings, successCallback, failureCallback) // 回调函数在执行异步任务(函数)前就要指定

Promise: start an asynchronous task => return a promise object => bind a callback function to the promise object (can even be specified after the asynchronous task ends)

// 2. 使用Promise
const promise = createAudioFileAsync(audioSettings);  // 执行2秒
setTimeout(() => {
    
    
  promise.then(successCallback, failureCallback) // 也可以获取
}, 3000);

2. Support chain calls, which can solve the problem of callback hell

Callback hell: Callback functions are nested, and the result of the asynchronous execution of the outer callback function is the condition for the execution of the inner nested callback function.

doSomething(function(result) {
    
    
  doSomethingElse(result, function(newResult) {
    
    
    doThirdThing(newResult, function(finalResult) {
    
    
      console.log('Got the final result:' + finalResult)
    }, failureCallback)
  }, failureCallback)
}, failureCallback)

promiseSolving Callback Hell with Chained Calls

doSomething()
  .then(result => doSomethingElse(result))
  .then(newResult => doThirdThing(newResult))
  .then(finalResult => {
    
    console.log('Got the final result:' + finalResult)})
  .catch(failureCallback)

Implementing Ajax with Promises

const getJSON = function(url) {
    
    
  const promise = new Promise(function(resolve, reject){
    
    
    const handler = function() {
    
    
      if (this.readyState !== 4) {
    
    
        return;
      }
      if (this.status === 200) {
    
    
        resolve(this.response);
      } else {
    
    
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
    
    
  console.log('Contents: ' + json);
}, function(error) {
    
    
  console.error('出错了', error);
});

In the above code, getJSON is an encapsulation of the XMLHttpRequest object, which is used to issue an HTTP request for JSON data and return a Promise object. It should be noted that inside getJSON, both the resolve function and the reject function are called with parameters.

Second, the use of Promise

1. Promise constructor: Promise(executor) {}

  • executor function:Synchronous execution (resolve, reject) => {}
  • resolve function: the function resolve(value) called when the internal definition succeeds
  • reject function: the function reject(reason) called when the internal definition fails

Description: The executor is the executor, which will immediately call back synchronously inside the Promise, and the asynchronous operation resolve/reject will be executed in the executor

2. Promise.prototype.then method:(onResolved, onRejected) => {}

指定两个回调(成功+失败)

(1) onResolvedFunction: successful callback function(value) => {}

(2) onRejectedFunction: callback function for failure(reason) => {}

Description: Specify valuethe success callback for success and reason the failure callback for failure, and return a new promiseobject

2, Promise.prototype.catch method:p.(onRejected) => {}

Specify a callback for failure

(1) onRejected function: failed callback function (reason) => {}

Explanation: This is then()syntactic sugar, equivalent to:then(undefined, onRejected)

new Promise((resolve, reject) => {
    
     // excutor执行器函数
	 setTimeout(() => {
    
    
	   if(...) {
    
    
	     resolve('成功的数据') // resolve()函数
	   } else {
    
     
	     reject('失败的数据') //reject()函数
	    }
	 }, 1000)
}).then(
	 value => {
    
     // onResolved()函数
	 console.log(value) // 成功的数据
}).catch(
	 reason => {
    
     // onRejected()函数
	  console.log(reason) // 失败的数据
	}
)

3. Promise.resolve method:Promise.resolve(value) => {}

Returns a success/failure promiseobject

value: success data or promiseobject

1. If the incoming parameter is an object of non-Promise type, the returned result is a successful promise object

let p1 = Promise.resolve(521);
console.log(p1); // Promise {<fulfilled>: 521}

insert image description here
2. If the incoming parameter is Promisean object, the result of the parameter determines resolvethe result of

let p2 = Promise.resolve(new Promise((resolve, reject) => {
    
    
    // resolve('OK'); // 成功的Promise
    reject('Error');
}));
console.log(p2);
p2.catch(reason => {
    
    
    console.log(reason);
})

insert image description here

4. Promise.reject method:Promise.resolve(reason) => {}

(1) reason: Reason for failure

Description: Returns a failed promiseobject

let p = Promise.reject(521);
let p2 = Promise.reject('iloveyou');
let p3 = Promise.reject(new Promise((resolve, reject) => {
    
    
    resolve('OK');
}));

console.log(p);
console.log(p2);
console.log(p3);

insert image description here
Promise.resolve()The / Promise.reject()method is a syntactic sugar to quickly get the Promise object

5. Promise.all method:Promise.all(iterable) => {}

  • iterablepromise: An iterable object containing n , such as ArrayorString
  • Returns a new one that succeeds promiseonly if all of them succeed, and fails directly if one fails.promise
let p1 = new Promise((resolve, reject) => {
    
    
  resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');

const result = Promise.all([p1, p2, p3]);
console.log(result);

insert image description here

let p1 = new Promise((resolve, reject) => {
    
    
  resolve('OK');
})
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('Oh Yeah');

const result = Promise.all([p1, p2, p3]);
console.log(result);

insert image description here

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

const pAll = Promise.all([p1, p2, p3])
const pAll2 = Promise.all([p1, p2])
//因为其中p3是失败所以pAll失败
pAll.then(
value => {
    
    
   console.log('all onResolved()', value)
 },
reason => {
    
    
   console.log('all onRejected()', reason) 
 }
)
// all onRejected() 3
pAll2.then(
values => {
    
    
   console.log('all onResolved()', values)
 },
reason => {
    
    
   console.log('all onRejected()', reason) 
 }
)
// all onResolved() [1, 2]

7. Promise.race method: Promise.race(iterable) => {}

  • iterablepromise: An iterable object containing n , such as ArrayorString
  • Returns a new promise, first completed promiseresult state which is the final result state.
const pRace = Promise.race([p1, p2, p3])
// 谁先完成就输出谁(不管是成功还是失败)
const p1 = new Promise((resolve, reject) => {
    
    
 setTimeout(() => {
    
    
   resolve(1)
 }, 1000)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

pRace.then(
value => {
    
    
   console.log('race onResolved()', value)
 },
reason => {
    
    
   console.log('race onRejected()', reason) 
 }
)
//race onResolved() 2
let p1 = new Promise((resolve, reject) => {
    
    
  setTimeout(() => {
    
    
      resolve('OK');
  }, 1000);
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');

//调用
const result = Promise.race([p1, p2, p3]);

console.log(result);

insert image description here

3. Several key issues of promise

1. How to change the state of promise?

(1) resolve(value): If the current is pendingwill becomeresolved

(2) reject(reason): If it is currently, pendingit will become `rejected``

(3) Throwing an exception: If it is currently, pendingit will becomerejected

const p = new Promise((resolve, reject) => {
    
    
  //resolve(1) // promise变为resolved成功状态
  //reject(2) // promise变为rejected失败状态
  throw new Error('出错了') // 抛出异常,promise变为rejected失败状态,reason为抛出的error
})
p.then(
  value => {
    
    },
  reason => {
    
    console.log('reason',reason)}
)
// reason Error:出错了

2. A promise specifies multiple success/failure callback functions, will they all be called?

Called when the promise changes to the corresponding state

const p = new Promise((resolve, reject) => {
    
    
  //resolve(1)
  reject(2)
})
p.then(
  value => {
    
    },
  reason => {
    
    console.log('reason',reason)}
)
p.then(
  value => {
    
    },
  reason => {
    
    console.log('reason2',reason)}
)
// reason 2
// reason2 2

3. Which one should change the promise state and specify the callback function first?

(1) Both are possible. Under normal circumstances, the callback is specified first and then the state is changed, but it is also possible to change the state first and then specify the callback

(2) How to change the state first and then specify the callback?

① Call resolve()/reject() directly in the executor

② Delay longer before calling then()

let p = new Promise((resolve, reject) => {
    
    
  // setTimeout(() => {
    
    
      resolve('OK');
  // }, 1000); // 有异步就先指定回调,否则先改变状态
});

p.then(value => {
    
    
  console.log(value);
},reason=>{
    
    
  
})

(3) When will the data be available?

① If the callback is specified first, then when the state changes, the callback function will be called to get the data

② If the state is changed first, then when the callback is specified, the callback function will be called to get the data

new Promise((resolve, reject) => {
    
    
  setTimeout(() => {
    
    
    resolve(1) // 改变状态
  }, 1000)
}).then( // 指定回调函数 (先指定)
  value => {
    
    },
  reason =>{
    
    }
)

At this time, first specify the callback function, save the currently specified callback function; then change the state (at the same time specify the data), and then execute the previously saved callback function asynchronously.

new Promise((resolve, reject) => {
    
    
  resolve(1) // 改变状态
}).then( // 指定回调函数
  value => {
    
    },
  reason =>{
    
    }
)

This way of writing, first change the state (at the same time specify the data), then specify the callback function (no need to save again), and directly execute the callback function asynchronously

4. What determines the result state of the new promise returned by promise.then()?

(1) Simple expression: determined by the execution result of the callback function specified by then()

let p = new Promise((resolve, reject) => {
    
    
  resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
    
    
  console.log(value);
}, reason => {
    
    
  console.warn(reason);
});

console.log(result);

insert image description here

(2) Detailed expression:

① If an exception is thrown, the new promise becomes rejected, reason is the thrown exception

let p = new Promise((resolve, reject) => {
    
    
  resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
    
    
  //1. 抛出错误
  throw '出了问题';
}, reason => {
    
    
  console.warn(reason);
});

console.log(result);

insert image description here
② If any non-promise value is returned, the new promise becomes resolved, and value is the returned value

let p = new Promise((resolve, reject) => {
    
    
  resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
    
    
	//2. 返回结果是非 Promise 类型的对象
	return 521;
}, reason => {
    
    
  console.warn(reason);
});

console.log(result);

insert image description here

③ If another new promise is returned, the result of this promise will become the result of the new promise

let p = new Promise((resolve, reject) => {
    
    
  resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
    
    
	//3. 返回结果是 Promise 对象
	return new Promise((resolve, reject) => {
    
    
		// resolve('success');
		reject('error');
	});
}, reason => {
    
    
  console.warn(reason);
});

console.log(result);

insert image description here

new Promise((resolve, reject) => {
    
    
  resolve(1)
}).then(
  value => {
    
    
    console.log('onResolved1()', value)
  },
  reason => {
    
    
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    
    
    console.log('onResolved2()', value)
  },
  reason => {
    
    
    console.log('onRejected2()', reason)
  }
)
// onResolved1() 1
// onResolved2() undefined
new Promise((resolve, reject) => {
    
    
  resolve(1)
}).then(
  value => {
    
    
    console.log('onResolved1()', value)
    //return 2                   // onResolved2() 2
    //return Promise.resolve(3)  // onResolved2() 3
    //return Promise.reject(4)   // onRejected2() 4
    //throw 5                    // onRejected2() 5
  },
  reason => {
    
    
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    
    
    console.log('onResolved2()', value)
  },
  reason => {
    
    
    console.log('onRejected2()', reason)
  }
)
// onResolved1() 1
// onResolved2() undefined
// Promise {<fulfilled>: undefined}
// 对应输出如上所示

5. How does promise chain multiple operation tasks?

(1) promisereturns then()a new chain call promisethat can be openedthen()

(2) thenMultiple synchronous/asynchronous tasks are connected in series through the chain call of

let p = new Promise((resolve, reject) => {
    
    
  setTimeout(() => {
    
    
      resolve('OK');
  }, 1000);
});

p.then(value => {
    
    
  return new Promise((resolve, reject) => {
    
    
      resolve("success");
  });
}).then(value => {
    
    
  console.log(value); // success
}).then(value => {
    
    
  console.log(value); // undefined
})
new Promise((resolve, reject) => {
    
    
  setTimeout(() => {
    
    
    console.log('执行任务1(异步)')
    resolve(1)
  }, 1000)
}).then(
  value => {
    
    
    console.log('任务1的结果', value)
    console.log('执行任务2(同步)')
    return 2 // 同步任务直接return返回结果
  }
).then(
  value => {
    
    
    console.log('任务2的结果', value)
    return new Promise((resolve, reject) => {
    
     // 异步任务需要包裹在Promise对象中
      setTimeout(() => {
    
    
        console.log('执行任务3(异步)')
        resolve(3)
      }, 1000)
    })
  }
).then(
  value => {
    
    
    console.log('任务3的结果', value)
  }
)
// 执行任务1(异步)
// 任务1的结果 1
// 执行任务2(同步)
// 任务2的结果 2
// 执行任务3(异步)
// 任务3的结果 3

6. Break promise chain?

(1) When using promisethe thenchain call of , it will be interrupted in the middle, and the subsequent callback function will not be called

(2) Methods:penddingReturn a state promiseobject in the callback function

new Promise((resolve, reject) => {
    
    
   //resolve(1)
   reject(1)
}).then(
  value => {
    
    
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value => {
    
    
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value => {
    
    
    console.log('onResolved3()', value)
  }
).catch(
  reason => {
    
    
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    
    
    console.log('onResolved4()', value)
  },
  reason => {
    
    
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1
// onResolved4() undefined

Guess you like

Origin blog.csdn.net/Bon_nenul/article/details/128224182