gpt4 book ai didi

javascript - JavaScript promise 如何执行其代码?

转载 作者:行者123 更新时间:2023-12-01 01:52:32 25 4
gpt4 key购买 nike

这是我从https://scotch.io/tutorials/javascript-promises-for-dummies窃取并稍加修改的一些代码。

var momIsHappy = false;

var getAPhone = function (whatToDoIfPhoneIsPurchased,
whatToDoIfPhoneIsNotPurchased) {
fulfillPromiseToPurchasePhone = whatToDoIfPhoneIsPurchased;
breakPromiseToPurchasePhone = whatToDoIfPhoneIsNotPurchased;

if (momIsHappy) {
var phone = {
brand: 'Samsung',
color: 'black'
};
fulfillPromiseToPurchasePhone(phone); // fulfilled
} else {
var reason = new Error('mom is not happy');
breakPromiseToPurchasePhone(reason); // reject
}
}

var aPhoneIMightGet = new Promise(getAPhone);

var playWithNewPhone = function () {
findOutIfIGetPhone = aPhoneIMightGet;

findOutIfIGetPhone
.then(function (aPhone) {
// yay, you got a new phone
console.log(aPhone);
// output: { brand: 'Samsung', color: 'black' }
})
.catch(function (error) {
// oops, mom don't buy it
console.log(error.message);
// output: 'mom is not happy'
});
};


我不明白的是:什么时候调用 getAPhone?我没打电话谁叫的什么时候?怎么样?

最佳答案

让我们备份一下并描述Promise构造函数的作用。 Promise构造函数传递给一个同步调用的回调。该回调(通常称为“ Promise executor回调”)背后的想法是,它将启动一些异步操作,然后立即返回。稍后,当异步操作完成后,它将解析或拒绝该承诺。

这是一个简单的示例,我们可以逐步进行操作(您可以在下面的代码段中运行此示例以查看日志记录顺序):



console.log("0");
let p = new Promise(function(resolve, reject) {
console.log("1");
setTimeout(function() {
console.log("2");
resolve("done");
}, 1000);
}).then(function(val) {
console.log("3");
});
console.log("4");





您将获得以下输出:

0     // start of the code
1 // Promise executor callback called and setTimeout() initiated
4 // Promise created and now initialized
2 // setTimeout fires
3 // Promise gets resolved and .then() handler called


而且,这是发生的事件的顺序:


console.log("0");运行
您调用 new Promise()并将其传递给回调函数
Promise构造函数运行,创建一个Promise对象并同步调用回调函数
回调函数的目的是启动一些非阻塞的异步操作(在这种情况下为简单的 setTimeout()),但是它可能要复杂得多,例如执行一些文件操作,搜索数据库等。 。
回调函数传递了两个参数,每个参数都是一个函数。当回调中启动的异步操作完成时,回调应调用这两个函数之一。如果这是典型的异步操作,则回调将启动异步操作,然后返回。然后,在某个时间之后,将调用与异步操作关联的不同回调,然后根据该操作是成功还是返回错误,该回调将调用传递给该回调的两个函数之一(我将其命名为 resolvereject在我的示例中,您的示例选择了更长的名称。
在我的代码示例中,Promise回调(称为Promise执行程序)立即登录到控制台,然后调用 setTimeout()。由于 setTimeout()是非阻塞且异步的,因此它将启动计时器并立即返回。此时,Promise执行程序回调已完成并返回。
计时器现在正在运行,promise执行程序回调已运行并返回。 promise构造函数完成后,它返回新的Promise对象。
然后,在promise上调用 .then()方法。这会为promise注册一个完成回调,然后立即返回。从技术上讲,它返回第二个Promise,该Promise链接到使用Promise构造函数创建的第一个Promise。已注册的此 .then()回调已保存,但尚未调用。
现在,此示例中的最后一行代码将执行,并将 4记录到控制台。
此代码已完成(目前)。随后执行的任何其他代码将立即执行,或者如果没有其他代码,则Javascript解释器将返回事件循环并等待下一个事件发生。
稍后,计时器启动。它在Javascript事件队列中插入一个事件,当解释器完成其他工作后,再从事件队列中获取下一个事件,它将调用传递给 setTimeout()的回调。
当该 setTimeout()回调执行时,它将记录 2,然后调用 resolve("done")。调用 resolve()会解析第一个承诺,并告诉它随后触发任何 .then()处理程序并调用它们。
此时,将调用传递给 .then()的回调并将其记录为 3并完成所有操作。


现在回答有关代码示例的一些特定问题:


  我不明白的是:什么时候调用getAPhone?我没打电话谁叫的什么时候?怎么样?


您将 getAPhone传递给Promise构造函数。 Promise构造函数将其作为运行构造函数以创建新Promise对象的一部分进行调用。

这是一个简单的例子,说明如何发生:

function doIt(someCallback) {
someCallback("hi");
}

function myCallback(greeting) {
console.log(greeting);
}

doIt(myCallback); // logs "greeting"


调用doIt时,会向其传递函数引用(本质上是指向函数的指针)。这样,您要调用的函数就可以在调用函数时使用其想要的任何参数来调用该函数。在这种情况下, doIt()希望您向其传递一个函数引用,它将立即调用该函数并将其传递给 "hi"


  那么,为什么promise构造函数在运行我的函数时不只是阻塞我的代码呢?如果构造函数所做的所有事情都立即为我调用了一个函数,为什么它与直接调用该函数有什么不同?


promise构造函数是同步运行的(当您调用 new Promise()时)。 Promise构造函数可以同步运行promise executor回调函数。但是,它通常所做的只是启动异步和非阻塞操作,然后立即返回。然后,异步操作将在后台运行,并在将来完成时触发它自己的回调。


  那么,为什么Promise的构造函数中没有代码块呢?它不是像其他所有函数一样在调用堆栈上具有功能吗?


Promise构造函数正在阻塞。它直到完成才返回。与其他所有函数一样,它是调用堆栈上的函数。

在这里可能使您感到困惑的是,您的 getAPhone()示例不包含任何异步代码。这是完全同步的。完全没有理由在该代码中使用promise。

这是该函数的简化版本:

var momIsHappy = false;

var getAPhone = function (resolve, reject) {
if (momIsHappy) {
var phone = {
brand: 'Samsung',
color: 'black'
};
resolve(phone); // fulfilled
} else {
var reason = new Error('mom is not happy');
reject(reason); // reject
}
}


所有这些操作就是检查 momIsHappy,然后立即解决或拒绝该诺言。这里没有异步操作。完全没有理由在您的示例中使用promise。承诺是用于管理和协调异步操作的工具。如果您没有任何异步操作,则不应使用它们,因为当可以使用普通和更简单的函数调用时,它们会增加同步代码的复杂性。使用异步操作,可能难以协调和管理异步操作以及错误处理,尤其是当需要对多个异步操作进行排序或协调并处理所有错误时。这就是承诺的目的。

因此,在您的特定情况下,您可以将 getAPhone()设为常规函数,直接调用它,而根本不使用promises。

关于javascript - JavaScript promise 如何执行其代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51343968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com