javascript - promise 是不可变的及其保证值(value)是什么意思?

标签 javascript callback ecmascript-6 es6-promise

我正在尝试理解 differences between es6 promises and regular callbacks但不要得到下面的例子。有人可以展示使用回调执行以下操作会是什么样子吗?

// an immediately resolved promise
var p2 = Promise.resolve("foo"); 

// can get it after the fact, unlike events
p2.then((res) => console.log(res)); 

var p = new Promise(function(resolve, reject) {  
   setTimeout(() => resolve(4), 2000);
});

// handler can't change promise, just value
p.then((res) => {  
  res += 2;  
  console.log(res);
});

// still gets 4
p.then((res) => console.log(res));

最佳答案

promise 是一种单向闩锁。一旦它被一个值解决或被一个原因拒绝,它的状态和值/原因就永远不会改变。所以,无论你对同一个 promise 执行多少次 .then(),你总是会得到相同的结果。这就是“不可变”的意思。

我不确定您所说的保证值是什么意思。无法保证 promise 会永远解决。它可能会拒绝(因此没有值),或者如果操作永远不会完成,它可能永远不会解决或拒绝。

promises 设计的操作类型的一个例子是异步操作,例如 Ajax 调用或从文件中读取一些字节。操作是异步的(解释器的正常执行在操作开始后继续)并且操作有特定的开始和结束。在大多数情况下,操作可能会成功完成,在这种情况下它可以有一个值,或者它可能以错误结束,在这种情况下它有一个错误。 value 和 error 都可以是对象,因此如果结果不仅仅是一个简单的值,它们可以具有许多属性。

例如,Ajax 调用具有特定的开始和结束。它不能超过一次结束,所以它是 promises 的完美匹配。您得到一个表示 ajax 操作最终结果的 promise 。然后,您注册一个 fulfill 处理程序和一个 reject 处理程序,当操作完成时将调用其中一个。

Plain callbacks 只是回调,每次调用时都可以赋予不同的值,并且可以多次调用。

如果您希望在某些操作完成并且操作具有特定的开始和结束时收到一次且仅一次的通知,请使用 promise 。

如果您想多次收到通知,请使用普通回调或事件监听器或观察者或其他可以多次触发的机制。


举个简单的例子,setTimeout() 与 promise 配合得很好。

function delay(t) {
    return new Promise((resolve, reject) => {
        resolve();
    }, t);
}

// delay 100ms before starting the operation
delay(100).then(run);

或者,使用 Bluebird Promise 库进行更复杂的操作以循环访问 URL 列表、下载内容、解析内容、在内容中查找某些特定的 URL,然后将它们全部收集起来(也称为抓取) :

const Promise = require('bluebird');
const request = Promise.promisifyAll(require('request'), {multiArgs: true});
const cheerio = require('cheerio');

function getAsync() {
    return request.getAsync.apply(request, arguments).then(argArray => {
        // return only the response html
        if (argArray[0].statusCode !== 200) {
            throw new Error("response statusCode = " + argArray[0].statusCode);
        }
        return argArray[1];
    });
}

const urls = [....];
Promise.mapSeries(urls, url => {
     return getAsync({url: url, gzip: true}).then(html => {
         let $ = cheerio.load(html);
         let resources = $("#external_resources_list li a.filename");
         resources.each(index, link) => {
             let href = $(link).attr("href");
             console.log(href);
             results.push(href);
         });
     }).catch(err => {
         // log error, but keep going
         console.log(url, err);
     });
}).then(() => {
    // got all results here
    console.log(results);
});

而且,setInterval() 根本不适用于 promise ,因为它想在每次时间间隔过去时重复通知您,而这根本不适用于 promise 。坚持使用 setInterval() 的回调。

关于javascript - promise 是不可变的及其保证值(value)是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42602868/

相关文章:

javascript - C语言中的二叉树装箱算法

javascript - 计算 Canvas 中彩色方 block 的数量

jquery - 让 jQuery 在执行下一行之前等待一个 .each 函数完成?

node.js - NodeJS MongoDB 回调 hell

javascript - 在 for 循环之后执行 javascript

javascript - 你能选择用 Babel 转译哪些 ES6 特性吗?

javascript - 获取 API - 返回的变量未定义

javascript - 如何检查一个 json 对象数组中的 id 是否存在于另一个嵌套的 json 对象数组中?

javascript - 单击下一步按钮时自动调整大小至全屏

javascript - React 计时器代码不起作用,每次都输出 2