JavaScript Promise (期约)

2023-05-17 15:49:13 浏览数 (2)

# Promis

不把自己程序的 continuation 传给第三方,而是希望第三方给我们提供了解其任务何时结束的能力,然后由我们自己的代码来决定下一步做什么。这种范式就称为 Promise

# 未来值

运算 x y 假定了 x 和 y 都已经设定。

代码语言:javascript复制
var x, y = 2;

console.log(x   y);

xy 当作未来值,并且表达了一个运算 add() 。这个运算(从外部看)不在意 xy 现在是否都已经可用。

代码语言:javascript复制
function add (getX, getY, cb) {
  var x, y;
  getX (function (xVal) {
    x = xVal;
    if (y != undefined) {
      cb (x   y);
    }
  });
  getY (function (yVal) {
    y = yVal;
    if (x != undefined) {
      cb (x   y);
    }
  });
}
add(fetchX, fetchY, function (sum) {
  console.log(sum);
});

为了统一处理现在将来 ,我们把它们都变成了将来 ,即所有的操作都成了异步的。

试试用 Promise 来表达 x :

代码语言:javascript复制
function add (xPromise, yPromise) {
  return Promise.all([xPromise, yPromise])
  .then(function (values) {
    return values[0]   values[1];
  });
}
add(fetchX(), fetchY())
.then(
  function (sum) {
    console.log(sum);
  },
  function (err) {
    console.log(err);
  }
);

从外部看,由于 Promise 封装了依赖于时间的状态——等待底层值的完成或拒绝,所以 Promise 本身是与时间无关的。因此,Promise 可以按照可预测的方式组成(组合),而不用关心时序或底层的结果。

一旦 Promise 决议,它就永远保持在这个状态。此时它就成为了不变值 (immutable value),可以根据需求多次查看。

Promise 是一种封装和组合未来值的易于复用的机制。

# 完成事件

单独的 Promise 展示了未来值的特性。也可以从另外一个角度看待 Promise 的决议:一种在异步任务中作为两个或更多步骤的流程控制机制,时序上的 this-then-that。

在典型的 JavaScript 风格中,如果需要侦听某个通知,可以把对通知的需求重新组织为对 foo() 发出的一个完成事件 (completion event, 或 continuation 事件)的侦听。

使用回调的话,通知就是任务(foo())调用的回调。而使用 Promise 的话,把这个关系反转了过来,侦听来自 foo() 的事件,然后在得到通知的时候,根据情况继续。

代码语言:javascript复制
foo (x) {
  // 一些耗时的操作
}

foo(2022);

on (foo 'completion') {
  // 一些操作
}

on (foo 'error') {
  // 一些操作
}

调用 foo() ,然后建立了两个事件侦听 器,一个用于"completion" ,一个用于 "error" —— foo() 调用的两种可能结果。从本质上讲,foo() 并不需要了解调用代码订阅了这些事件,这样就很好地实现了关注点分离

代码语言:javascript复制
function foo (x) {
  // 一些耗时的操作
  return listener;
}

var evt = foo(2022);

evt.on('completion', function () {
  // 一些操作
});

evt.on('error', function () {
  // 一些操作
});

复制

0 人点赞