类型 'Promise<number>' 不可分配给类型 'number'

j.h*_*her 5 promise typescript

我正在尝试从承诺中返回数字:函数getActualId调用来自chrome.local.storage并返回一个承诺:

function getActualId(){
    return new Promise(function (resolve) {
        chrome.storage.sync.get({
            userId: true
        }, function (userId) {
            resolve(userId.userId);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

这个函数得到了正确的值,但是当我从另一个函数调用它时,我不断得到getId函数返回 aPromise<number>而不是承诺。

async function getId(){
    let id:number = 0;
    await getActualId().then( function(userid:number){
        id =  userid;
    })
    return id
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到idfromgetId而不是 a的真正价值promise<number>

T.J*_*der 7

您几乎从不thenasync函数中使用。¹函数的重点async是您可以使用它await。在您的情况下,您希望将结果分配await getActualId()id

async function getId(){
    let id:number = await getActualId();
    return id;
}
Run Code Online (Sandbox Code Playgroud)

(虽然不清楚为什么需要存在该函数,但它只是 . 的包装getActualId。)

getActualId但是,有一个问题,如果我们解决了我们不需要idin上的类型注释的问题getIdgetActualId缺少其返回类型注释,因此它隐式返回Promise<any>. 如果它回来了Promise<number>,你需要说:

function getActualId(): Promise<number> {
    return new Promise(function (resolve) {
        chrome.storage.sync.get({
            userId: true
        }, function (userId) {
            resolve(userId.userId);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

操场上的例子

function getActualId(): Promise<number> {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(Math.floor(Math.random() * 100));
        }, 100);
    });
}
async function getId() {
    let id = await getActualId();
    return id;
}
Run Code Online (Sandbox Code Playgroud)

如果您将鼠标悬停id在 中getId,您会看到 TypeScript 知道这是number由于 的签名getActualId,因此我们不需要类型注释,因为 TypeScript 可以推断出它。


¹“几乎从不”是指真正的几乎从不。我能想到的唯一示例是,如果您有一堆操作要并行执行(因此您正在使用Promise.all),并且您需要对其中一个操作的结果进行转换。那么你可能会这样做:

const [first, second, third] = await Promise.all([
   firstOp(),
   secondOp().then(value => value.toUpperCase()),
   thirdOp()
]);
Run Code Online (Sandbox Code Playgroud)

因为使用awaitonsecondOp会延迟开始thirdOp(而上述不会)。