静下心来的个人专栏
上一篇

构建新的(不确定)Promise

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

构建不确定Promise

一般情况下使用Promise构造函数创建新的Promise。这个构造函数接受一个参数:一个称为 executor 的函数,它包含初始化 promise 的代码。执行器被传递了两个名为resolve() 和reject() 的函数作为参数。 当 executor 成功完成时调用 resolve() 函数表示 promise操作成果,或者调用 reject() 函数表示操作失败。

下面是一个使用旧的 XMLHttpRequest 浏览器 API 的示例:

// Browser example
function requestURL(url) {
 	return new Promise((resolve, reject) => {
 		const xhr = new XMLHttpRequest();

 		// assign event handlers
 		xhr.addEventListener("load"	, () => 	{
 			resolve({
 				status: xhr.status,
 				text: xhr.responseText
 			});
 		});

 		xhr.addEventListener("error", error => 	{
 			reject(error);
 		});
 		// send the request
 		xhr.open(	"get"	, url);
 			xhr.send();
 		});
 	}

const promise = requestURL("books.json");

// listen for both fulfillment and rejection
promise.then(response => {
 	// fulfillment
 	console.log(response.status);
 	console.log(response.text);
}, reason => {
 	// rejection
 	console.error(reason.message);
});

在此示例中,XMLHttpRequest 调用被包装在一个 Promise 中。 load 事件指示请求何时成功完成,因此 promise 执行器在事件处理程序中调用 resolve()。类似地,错误事件指示请求何时无法完成,因此在该事件处理程序中调用 reject() . 您可以按照相同的过程(在事件处理程序中使用 resolve() 和 reject())将基于事件的功能转换为基于承诺的功能。

 

executor 的一个重要方面是它们在创建 Promise 时立即运行。 在前面的示例中,创建了 xhr 对象,分配了事件处理程序,并在从 requestURL() 返回 Promise 之前启动了调用。 当在执行器内部调用 resolve() 或 reject() 时,promise 的状态和值会立即设置,但所有的 promise 处理程序(作为微任务)在当前脚本作业完成之前不会执行。 例如,考虑一下如果在执行程序中立即调用 resolve() 会发生什么,如下代码所示:

const promise = new Promise((resolve, reject) => {
  console.log("Executor");
  resolve(42);
});

promise.then(result => {
  console.log(result);
});

console.log("Hi!");

在这里,promise 立即解决,没有任何延迟,然后使用 then() 添加一个实现处理程序以输出结果。 即使promise在履行时已经解决添加处理程序后,输出将如下:

Executor
Hi!
42

执行器首先运行,将“Executor”输出到控制台。 接下来,完成处理程序被分配但不会立即执行。 相反,会创建一个新的微任务以在当前脚本作业之后运行。 这意味着 console.log("Hi!") 在执行处理程序之前执行,在脚本的其余部分完成后输出42

一个promise只能被解析一次,所以如果你在一个执行器中多次调用resolve(),第一次之后的每个调用都会被忽略。

执行器错误

如果在 executor 中抛出错误,则调用 promise 的拒绝处理程序。 例如:

const promise = new Promise((resolve, reject) => {
  throw new Error("Uh oh!");
});

promise.catch(reason => {
  console.log(reason.message); // "Uh oh!"
});

在这段代码中,执行者故意抛出一个错误。 每个执行器内部都有一个隐式的 try-catch,以便捕获错误,然后将其传递给拒绝处理程序。 前面的例子等价于:

const promise = new Promise((resolve, reject) => {
  try {
    throw new Error("Uh oh!");
  } catch (ex) {
    reject(ex);
  }
});

promise.catch(reason => {
  console.log(reason.message); // "Uh oh!"
});

执行器处理捕获任何抛出的错误以简化这个常见用例,就像其他rejection一样,JavaScript 引擎抛出错误并在没有reject handler时停止执行。

 

 

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们