首页 > 解决方案 > 在 onclick 中解决 Promise

问题描述

我正在尝试使以下代码正常工作。第一个函数(prepareNewCard)在网页中创建一个 div,所以我使用一个 promise 来确保下一个函数(getSearchTerm)仅在创建 div 后执行。getSearchTerm 旨在使用先前创建的 div 中的搜索词进行解析。为了测试这一点,我正在尝试 console.log 搜索词。但是,搜索词被记录为 null,但是函数中的 console.log("here") 可以按预期工作。在我看来,承诺在 .onclick 之前解决,但我不明白这是怎么发生的。

这是两个函数的代码

function prepareNewCard() {
    //Most of this not relevant to the question, creating the div
    var currentCard = document.createElement("div");
    currentCard.className += " card";
    currentCard.className += " currentCard";
    var currentSearch = document.createElement("input");
    currentSearch.className += " searchInput";
    currentSearch.placeholder += "Enter a search term...";
    var searchButton = document.createElement("button");
    searchButton.className += " searchButton";

    //Create the card to be searched                                                    
    currentCard.appendChild(currentSearch);
    currentCard.appendChild(searchButton);

    //Add this card to the main div                                                     
    const searchResultsArea = document.getElementById("searchResults");

    //The promise being returned
    return new Promise(function(resolve, reject) {
            currentCards = document.getElementById(".currentCard");
            if (currentCards === null) {
                searchResultsArea.appendChild(currentCard);
                resolve(currentCard);
            } else {
                reject('Use your current card before creating a new one');
            }
        });
}

function getSearchTerm(currentCard) {
    currentSearchBar = currentCard.querySelector(".searchInput");
    currentSearchButton = currentCard.querySelector(".searchButton");

    currentSearchButton.onclick = function() {
        return new Promise(function(resolve, reject) {
                var currentSearchInput = currentSearchBar.value;
                if (currentSearchInput !== null) {
                    resolve(currentSearchInput);
                    console.log("here");
                } else {
                    reject("Please input search term");
                }
            });
    }
}

调用这些函数的代码在这里

    newCardButton.onclick = function() {
        prepareNewCard()
        .then(function(currentCard) {
                getSearchTerm(currentCard)
                .then(function(searchTerm) {
                     console.log(searchTerm)
                })  
                .catch(function(error) {
                    console.log(error)
                });
        })
        .catch(function(error) {
                console.log(error);
        });
    }

javascript 承诺不可能做到这一点吗?我已经为 promise .then 函数尝试了许多配置,但似乎都没有。提前致谢!

编辑:

这是另一个没有承诺的版本。

function prepareNewCard() {
    //Same code above to create div
    const searchResultsArea = document.getElementById("searchResults");
    searchResultsArea.appendChild(currentCard);
    return currentCard;
}

function getSearchTerm(currentCard) {
    currentSearchBar = currentCard.querySelector(".searchInput");
    currentSearchButton = currentCard.querySelector(".searchButton");

    currentSearchButton.onclick = function() {
    console.log("TEST");
    return currentSearchBar.value;
}

    let currentCard;
    let currentSearchTerm;
    newCardButton.onclick = function() {
    currentCard = prepareNewCard();
    currentSearchTerm = getSearchTerm(currentCard);
    console.log(currentSearchTerm);
}

上述代码的控制台如下所示:

单击 newcard 按钮并立即获得“未定义”以响应 console.log(currentSearchTerm)。然后,当单击动态创建 div 控制台中的 searchButton 时,会打印“TEST”,仅此而已。

标签: javascriptpromise

解决方案


问题是你从onclick处理函数返回一个promise,而不是从getSearchTerm它不返回任何东西,所以它应该是:

function getSearchTerm(currentCard) {
    currentSearchBar = currentCard.querySelector(".searchInput");
    currentSearchButton = currentCard.querySelector(".searchButton");

    return new Promise(function(resolve, reject) {
          currentSearchButton.onclick = function() {
                var currentSearchInput = currentSearchBar.value;
                if (currentSearchInput !== null) {
                    resolve(currentSearchInput);
                    console.log("here");
                } else {
                    reject("Please input search term");
                }
          }
     });
}

此外,返回一个 promiseprepareNewCard是完全没有必要的,因为它是同步的,相反,只需返回值或抛出错误:

currentCards = document.getElementById(".currentCard");
if (currentCards === null) {
    searchResultsArea.appendChild(currentCard);
    return currentCard;
} else {
    throw 'Use your current card before creating a new one';
}

推荐阅读