In-depth Understanding of ES6 011 [Learning Notes]

Promises and Asynchronous Programming

Because the execution engine is single-threaded, it needs to track the code that is about to run. This code is placed in a task queue. Whenever a piece of code is ready to execute, it is added to the task queue, and whenever a piece of code in the engine finishes execution, the event loop executes the next task in the queue. A Promise acts as a placeholder for the result of an asynchronous operation. It doesn't subscribe to an event or pass a callback function to the target function. Instead, it allows the function to return a Promise, like this...

Promise and Asynchronous Programming

Because the execution engine is single-threaded, it needs to track the code that is about to run. That code is placed in a task queue. Whenever a piece of code is ready to execute, it is added to the task queue. Whenever a piece of code in the engine finishes execution, the event loop executes the next task in the queue.

Promise acts as a placeholder for the result of an asynchronous operation. It doesn't subscribe to an event, nor does it pass a callback function to the target function. Instead, it makes the function return a Promise, like this:

// readFile承诺在未来的某个刻完成
let promise = readFile('txx.txt')

Promise Lifecycle

  • pending
  • fulfilled (Success)
  • rejected (Program error or some other reason)

The [[PromiseState]] internal property is used to represent the three states of a Promise. This property is not exposed on the Promise object, so the state of a Promise cannot be programmatically detected. Only when the Promise state changes can specific actions be taken via the then() method. Therefore, all Promises have a then method, which accepts two arguments: two callback functions for when it is fulfilled and when it is rejected.

If an object implements the then method mentioned above, we call that object a thenable object. All Promise objects are thenable objects, but not all thenable objects are Promises.

let promise = readFile("example.txt");
promise.then(function(contents){
  // 完成
},function(err){
  // 拒绝
})
promise.then(function(contents){
  // 完成
})

promise.then(null,function(err){
  // 拒绝
})
// catch等同于上面这种
promise.catch(function(err){
  // 拒绝
})

If a Promise is passed to the Promise.resolve() method or the Promise.reject() method, that Promise will be returned directly.

Rejection Handling in Node.js Environment

  • unhandledRejection
  • rejectionHandled
let rejected;
process.on("unhandledRejection",function(reason,promise){
  console.log(reason.message); // "Explosin"
  console.log(rejected === promise); // "Explosin"
})
rejected = Promise.reject(new Error('Explosin'))

Chaining Promises and Chained Return Values

let p1 = new Promise(function(resolve,reject){
  resolve(42)
})
p1.then(function(value){
  console.log(value)
  return value+1;
})
.then(function(value){
  console.log(value); // "43"
})

let p1 = new Promise(function(resolve,reject){
  reject(42)
})
p1.catch(function(value){
  console.log(value) // 42
  return value+1;
})
.then(function(value){
  console.log(value); // "43"
})

Returning Promises in a Promise Chain

Promise.all()

It accepts only one argument and returns a Promise. This argument is an iterable object containing multiple monitored Promises. The returned Promise will only be resolved when all Promises in the iterable object are resolved, and it will only be fulfilled when all Promises in the iterable object are fulfilled. As long as one Promise is rejected, the returned Promise will be rejected without waiting for all others to complete.

let p1 = new Promise(function(resolve,reject){
  resolve(42)
})
let p2 = new Promise(function(resolve,reject){
  reject(43)
})
let p3 = new Promise(function(resolve,reject){
  resolve(44)
})
let p4 =  Promise.all([p1,p2,p3])
p4.catch(function(value){
  console.log(Array.isArray(value)); //false
  console.log(value); // 43
})

Promise.race()

As long as one Promise resolves, there's no need to wait for all of them to complete. Once a Promise in the array is fulfilled, the Promise.race() method will also return a specific Promise, just like the Promise.all() method.

Promise Inheritance

class MyPromise extends Promise {
  // 使用默认的构造函数

  success(resolove,reject){
    return this.then(resolove,reject)
  }
  failure(reject){
    return this.catch(reject)
  }
}
let promise = new MyPromise(function(resolve,reject){
  resolve(42)
})
promise.success(function(value){
  console.log(value) // 42
})
.failure(function(value){
  console.log(value)
})

Promise-based Asynchronous Task Execution

Refactoring the previous file reading functionality. As long as every asynchronous operation returns a Promise, this process can be greatly simplified and made usable. Using Promises as a common interface for all asynchronous code can simplify the task executor.

let fs = require("fs");

function run(taskDef){
  // 创建迭代器
  let task = taskDef()

  // 开始执行任务
  let result = task.next();

  // 递归函数遍历
  (function step(){
    // 如果有更多任务要做
    if(!result.done){
      // 用一个Promise来解决会简化问题
      let promise = Promise.resolove(result.value);
      promise.then(function(value){
        result = task.next(value);
        step()
      })
      .catch(function(error){
        result = task.throw(error);
        step();
      })
    }

  }())
}
// 定义一个可用于任务执行器的函数
function readFile(filename){
  return new Promise(function(resolove,reject){
    fs.readFile(filename,function(err,contents){
      if(err){
        reject(err);
      } else {
        resolove(contents)
      }
    })
  })
}

// 执行一个任务
run(function *(){
  let contents = yield readFile("config.json");
  doSomethingWith(contents);
  console.log("Done")
})

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://www.walker-learn.xyz/archives/4337

(0)
Walker的头像Walker
上一篇 Mar 8, 2025 13:04
下一篇 Mar 8, 2025 12:52

Related Posts

  • Fearless forward, fist power unleashed.

    Striving is an attitude. Life is like a competition with no shortcuts; only through continuous training, breaking through, and surpassing oneself can one stand on their own stage. This is not merely a contest, but rather a self-awakening—daring to face the fight, daring to challenge, and daring to become a stronger version of oneself. The Spirit of Striving in Sports. Whether it's boxing, running, or strength training, every punch thrown, every bead of sweat, every moment of gritting one's teeth and persevering, is a tempering of both body and mind. Striving is not merely a confrontation, but an attitude—facing challenges without backing down; facing failure, ...

    Personal Feb 26, 2025
    1.4K00
  • Go Engineer System Course 013 [Study Notes]

    Order transactions, whether deducting inventory first or later, will both affect inventory and orders. Therefore, distributed transactions must be used to address business issues (e.g., unpaid orders). One approach is to deduct inventory only after successful payment (e.g., an order was placed, but there was no inventory at the time of payment). Another common method is to deduct inventory when the order is placed, but if payment isn't made, the order is returned/released upon timeout.

    Transactions and Distributed Transactions
    1. What is a transaction?
    A transaction is an important concept in database management systems. It is a collection of database operations, which either all execute successfully, or all...

    Personal Nov 25, 2025
    30200
  • Go Engineer's Comprehensive Course 017: Learning Notes

    Introduction to Rate Limiting, Circuit Breaking, and Degradation (with Sentinel Practical Application)
    Based on the key video points from Chapter 3 (3-1 to 3-9) of the courseware, this guide compiles a service protection introduction for beginners, helping them understand "why rate limiting, circuit breaking, and degradation are needed," and how to quickly get started with Sentinel.
    Learning Path at a Glance
    3-1 Understanding Service Avalanche and the Background of Rate Limiting, Circuit Breaking, and Degradation
    3-2 Comparing Sentinel and Hystrix to clarify technology selection
    3-3 Sen...

    Personal Nov 25, 2025
    25500
  • In-depth Understanding of ES6 013 [Study Notes]

    Code Encapsulation with Modules

    JavaScript loads code using a "share everything" approach to loading code, which is one of the most error-prone and confusing aspects of the language. Other languages use concepts like packages to define code scope. Before ES6, everything defined in every JavaScript file within an application shared a single global scope. As web applications became more complex and the amount of JavaScript code grew, this practice led to issues such as naming conflicts and security concerns. One of ES6's goals was to address the scoping issue…

    Personal Mar 8, 2025
    1.2K00
  • Go Engineer Systematic Course 008 [Study Notes]

    Orders and Shopping Cart
    First, copy the service code framework of 'srv' from the inventory service, then find and replace the corresponding name (order_srv).

    Fundamentals of Encryption Technology
    Symmetric Encryption
    Principle:
    Uses the same key for encryption and decryption.
    Like a single key that can both lock and unlock a door.
    Fast encryption speed, suitable for large data transfers.
    Use cases:
    Local file encryption
    Database content encryption
    Content encryption during large data transfers
    Fast communication between internal systems...

    Personal Nov 25, 2025
    27900
EN
简体中文 繁體中文 English